多線程與高併發-線程池7_1:交替打印A1b2c3……

題目

交替打印A1b2c3……

用Locksupport解決

package com.inspire.juc.c_026_00_interview.A1B2C3;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;

public class T2_00_LockSupport {
    static Thread t1=null,t2=null;

    public static void main(String[] args) {
        char[] aI="1234567".toCharArray();
        char[] aC="ABCDEFG".toCharArray();
        t1=new Thread(()->{
            for(char c:aI){
                System.out.println(c);
                LockSupport.unpark(t2);//喚醒t2
                LockSupport.park();//阻塞t1
            }
        },"t1");

        t2=new Thread(()->{
            for(char c:aC){
                LockSupport.park();//阻塞t2
                System.out.println(c);
                LockSupport.unpark(t1);//喚醒t1
            }
        },"t2");

        t1.start();
        t2.start();
    }
}

用synchronized、wait、notify解決

package com.inspire.juc.c_026_00_interview.A1B2C3;

public class T06_00_sync_wait_notify {
    public static void main(String[] args) {
        final Object o=new Object();
        char[] aI="123456".toCharArray();
        char[] aC="ABCDEF".toCharArray();
        new Thread(()->{
            synchronized (o){
                for(char i:aI){
                    System.out.println(i);
                    try {
                        o.notify();//喚醒t2
                        o.wait();//阻塞t1
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();//喚醒t1
            }
        },"t1").start();

        new Thread(()->{
            synchronized (o){
                for(char i:aC){
                    System.out.println(i);
                    try {
                        o.notify();//喚醒t1
                        o.wait();//阻塞t2
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();//喚醒t2
            }
        },"t2").start();
    }
}

新的要求:先輸出字母,再輸出數字

package com.inspire.juc.c_026_00_interview.A1B2C3;

public class T07_00_sync_wait_notify {
    private static volatile boolean t2start=false;

    public static void main(String[] args) {
        final Object o=new Object();
        char[] aI="123456".toCharArray();
        char[] aC="ABCDEF".toCharArray();
        new Thread(()->{
            synchronized (o){
                if(!t2start){//t2爲false時,t1等待
                    try {
                        o.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for(char c:aI){
                    System.out.println(c);
                    try {
                        o.notify();//喚醒t2
                        o.wait();//阻塞t1
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();
            }
        },"t1").start();

        new Thread(()->{
            synchronized (o){
                for(char c:aC){
                    System.out.println(c);
                    t2start=true;
                    try {
                        o.notify();//喚醒t1
                        o.wait();//阻塞t2
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();
            }
        },"t2").start();
    }
}

用一個condition來解決

package com.inspire.juc.c_026_00_interview.A1B2C3;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class T08_00_lock_condition {
    public static void main(String[] args) {
        Lock lock=new ReentrantLock();
        Condition condition=lock.newCondition();
        char[] aI="123456".toCharArray();
        char[] aC="ABCDEF".toCharArray();
        new Thread(()->{
            try {
                lock.lock();
                for(char c:aI){
                    System.out.println(c);
                    condition.signal();//喚醒t2
                    condition.await();//阻塞t1
                }
                condition.signal();//這一步很重要,記得喚醒t2
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        },"t1").start();

        new Thread(()->{
            try {
                lock.lock();
                for(char c:aC){
                    System.out.println(c);
                    condition.signal();//喚醒t1
                    condition.await();//阻塞t2
                }
                condition.signal();//記得喚醒t1
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        },"t2").start();
    }
}

用兩個condition來解決(和上一個比,更推薦這個)

package com.inspire.juc.c_026_00_interview.A1B2C3;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class T09_00_lock_condition {
    public static void main(String[] args) {
        char[] aI="123456".toCharArray();
        char[] aC="ABCDEF".toCharArray();
        Lock lock=new ReentrantLock();
        Condition T1Condition=lock.newCondition();
        Condition T2Condition=lock.newCondition();

        new Thread(()->{
            try {
                lock.lock();
                for(char c:aI){
                    System.out.println(c);
                    T2Condition.signal();
                    T1Condition.await();
                }
                T2Condition.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        },"t1").start();

        new Thread(()->{
            try {
                lock.lock();
                for(char c:aC){
                    System.out.println(c);
                    T1Condition.signal();
                    T2Condition.await();
                }
                T1Condition.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        },"t2").start();
    }
}

注意

condition的語法是
在這裏插入圖片描述
在這裏插入圖片描述

不使用鎖來實現

package com.inspire.juc.c_026_00_interview.A1B2C3;

public class T03_00_cas {
    enum ReadyToRun {T1, T2}

    static volatile ReadyToRun r = ReadyToRun.T1;

    public static void main(String[] args) {
        char[] aI = "123456".toCharArray();
        char[] aC = "ABCDEF".toCharArray();
        new Thread(() -> {
            for (char c : aI) {
                while (r == ReadyToRun.T2) {
                }
                System.out.println(c);
                r = ReadyToRun.T2;

            }
        }, "t1").start();

        new Thread(() -> {
            for (char c : aC) {
                while (r == ReadyToRun.T1) {
                }
                System.out.println(c);
                r = ReadyToRun.T1;

            }
        }, "t2").start();
    }
}

使用BlockingQueue來解決

package com.inspire.juc.c_026_00_interview.A1B2C3;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class T04_00_BlockingQueue {
    static BlockingQueue<String> q1=new ArrayBlockingQueue<>(1);
    static BlockingQueue<String> q2=new ArrayBlockingQueue<>(1);

    public static void main(String[] args) {
        char[] aI="123456".toCharArray();
        char[] aC="ABCDEF".toCharArray();
        new Thread(()->{
            for(char c:aI){
                System.out.println(c);
                try {
                    q1.put("ok");//阻塞當前線程
                    q2.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"t1").start();

        new Thread(()->{
            for(char c:aC){
                try {
                    q1.take();//獲取q1,使得q1不再阻塞,進而執行t1中的q2.take;從而t2不再阻塞,相當於給t2開鎖
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(c);
                try {
                    q2.put("ok");//阻塞當前線程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"t2").start();
    }
}

用TransferQueue來解決

TransferQueue:transfer一個數據,等待另一個線程來拿,拿完,隊列才能添加下一個數據,一般用於:等待一個結果,有了結果才能進行下一步,如面對面付款

package com.inspire.juc.c_026_00_interview.A1B2C3;

import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;

public class T13_TransferQueue {
    public static void main(String[] args) {
        char[] aI="123456".toCharArray();
        char[] aC="ABCDEF".toCharArray();
        TransferQueue<Character> queue=new LinkedTransferQueue<>();
        new Thread(()->{
            for(char c:aI){
                try {
                    System.out.println(queue.take());//1.等待接收 3.從queue取得c,並打印輸出
                    queue.transfer(c);//4.將c添加進queue
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"t1").start();
        new Thread(()->{
            for(char c:aC){
                try {
                    queue.transfer(c);//2.將c放進queue,等待接收 //6.將c放進queue,等待接收,循環往復
                    System.out.println(queue.take());//5.從queue取得c,並打印輸出
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        },"t2").start();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章