JUC-字符交替打印

108 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

字符交替打印

1.使用LockSupport

使用工具类LockSupport精准阻塞和唤醒线程 LockSupport.unpark() 唤醒 LockSupport.unpark() 阻塞 AQS就是使用这个工具类阻塞唤醒

public class LockSupport01 {
    static Thread t1,t2;
    public static void main(String[] args) {
        char[] a = "abcdefg".toCharArray();
        char[] b = "1234567".toCharArray();
         t1 = new Thread(() -> {
            for (char a1 : a) {
                System.out.println(a1);
                LockSupport.unpark(t2);
                LockSupport.park();
            }
        }, "t1");
        t2 = new Thread(()->{
            for (char b1:b) {
                LockSupport.park();
                System.out.println(b1);
                LockSupport.unpark(t1);
            }
        },"t2");
        t1.start();
        t2.start();
    }

    }

2.使用Synchronized

使用工具类Synchronized加锁 notify 唤醒 wait 阻塞

public class Synchronized02 {
    public static void main(String[] args) {
        Object o = new Object();
        char[] a = "abcdefg".toCharArray();
        char[] b = "1234567".toCharArray();
       new Thread(() -> {
           synchronized (o){
               for (char a1 : a) {
                   try {
                       System.out.println(a1);
                       o.notify();
                       o.wait();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
               o.notify(); //加这个是在结束的时候在唤醒一下其他线程,以免其他线程在阻塞状态
           }

        }, "t1").start();
    new Thread(()->{
        synchronized (o){
            for (char b1:b) {
                System.out.println(b1);
                o.notify();
                try {
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
           }
            o.notify();
        }
        },"t2").start();

    }
}

3.使用CountDownLatch控制先后顺序

使用CountDownLatch 可以实现先打印小a 或者数字1 控制开始顺序

public class CountDownLatch03 {
    //使用countDownLatch 控制线程执行先后顺序
    private static CountDownLatch countDownLatch =new CountDownLatch(1);
    public static void main(String[] args) {
        Object o = new Object();
        char[] a = "abcdefg".toCharArray();
        char[] b = "1234567".toCharArray();
       new Thread(() -> {
           try {
               countDownLatch.await();
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           synchronized (o){
               for (char a1 : a) {
                       System.out.println(a1);
                   o.notify();
                   try {
                       o.wait();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
           }
           o.notify();
        }, "t1").start();
    new Thread(()->{
        synchronized (o){
            for (char b1:b) {
                countDownLatch.countDown();
                System.out.println(b1);
                o.notify();
                try {
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            o.notify();
        }

        },"t2").start();

    }
}

4.使用ReentrantLock

使用ReentrantLock 可以实现两个以上的交替打印 Synchronized只能实现两个 Condition 的等待和唤醒

public class ReentrantLock04 {
    //使用countDownLatch 控制线程执行先后顺序
    private static ReentrantLock reentrantLock =new ReentrantLock();

    public static void main(String[] args) {
        Condition condition =reentrantLock.newCondition();
        Condition condition2 =reentrantLock.newCondition();
        Condition condition3 =reentrantLock.newCondition();
        Object o = new Object();
        char[] a = "abcdefg".toCharArray();
        char[] b = "1234567".toCharArray();
        char[] c = "ABCDEFG".toCharArray();
       new Thread(() -> {
           reentrantLock.lock();
           try {
               for (char a1 : a) {
                   System.out.println(a1);
                   condition2.signal();
                   condition.await();

               }
               condition2.signal();
           }catch (InterruptedException e) {
               e.printStackTrace();
           }finally {
               reentrantLock.unlock(); //不释放锁线程会一直存在
           }
        }, "t1").start();
    new Thread(()->{
        reentrantLock.lock();
        try {
            for (char b1:b) {
                System.out.println(b1);
                condition3.signal();
                condition2.await();
            }
            condition3.signal();
        }catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            reentrantLock.unlock(); //不释放锁线程会一直存在
        }
            },"t2").start();

        new Thread(()->{
            reentrantLock.lock();
            try {
                for (char c1:c) {
                    System.out.println(c1);
                    condition.signal();
                    condition3.await();
                }
                condition.signal();
            }catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
            reentrantLock.unlock(); //不释放锁线程会一直存在
            }
        },"t3").start();

    }
}