天下脸皮共十分
我占八分

三种异步方式实现顺序打印

三种同步模式交替输出比较

synchronized

 package tech.ityoung.study.demo.jvm.juc;
 ​
 import lombok.extern.slf4j.Slf4j;
 ​
 public class ConcrossExecutionDemo01 {
 ​
     public static void main(String[] args) {
         SynchronizedConCrossExecutor executor = new SynchronizedConCrossExecutor(5, "1");
         Thread t1 = new Thread(() -> executor.print("1", "1", "2"), "t1");
         Thread t2 = new Thread(() -> executor.print("2", "2", "3"), "t1");
         Thread t3 = new Thread(() -> executor.print("3", "3", "1"), "t1");
         t1.start();
         t2.start();
         t3.start();
    }
 }
 ​
 @Slf4j
 class SynchronizedConCrossExecutor {
     private Integer loopNum;
     private String nextMark;
 ​
     public void print(String str, String mark, String nextMark) {
         for (Integer i = 0; i < loopNum; i++) {
             synchronized (this) {
                 while (!this.nextMark.equals(mark)) {
                     try {
                         this.wait();
                    } catch (InterruptedException e) {
                         e.printStackTrace();
                    }
                }
                 log.info(str);
                 this.nextMark = nextMark;
                 notifyAll();
            }
        }
    }
 ​
     public SynchronizedConCrossExecutor(Integer loopNum, String nextMark) {
         this.loopNum = loopNum;
         this.nextMark = nextMark;
    }
 }

reentrantlock

 package tech.ityoung.study.demo.jvm.juc;
 ​
 import lombok.extern.slf4j.Slf4j;
 ​
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 ​
 public class ConCrossExecutionDemo2 {
     public static void main(String[] args) throws InterruptedException {
         ReentrantLockConCrossExecutor executor = new ReentrantLockConCrossExecutor(5);
         Condition c1 = executor.newCondition();
         Condition c2 = executor.newCondition();
         Condition c3 = executor.newCondition();
         Thread t1 = new Thread(() -> executor.print("1", c1, c2), "t1");
         Thread t2 = new Thread(() -> executor.print("2", c2, c3), "t2");
         Thread t3 = new Thread(() -> executor.print("3", c3, c1), "t3");
         t1.start();
         t2.start();
         t3.start();
         Thread.sleep(1000);
         // 如果线程1未进入condition1,则会发生死锁
         executor.start(c1);
    }
 }
 ​
 @Slf4j
 class ReentrantLockConCrossExecutor extends ReentrantLock {
     private Integer loopNum;
 ​
     public ReentrantLockConCrossExecutor(Integer loopNum) {
         this.loopNum = loopNum;
    }
 ​
     public void start(Condition first) {
         try {
             this.lock();
             first.signal();
        } finally {
             this.unlock();
        }
    }
 ​
     public void print(String str, Condition current, Condition next) {
         for (int i = 0; i < loopNum; i++) {
             this.lock();
             try {
                 current.await();
                 log.info(str);
                 next.signal();
            } catch (InterruptedException e) {
                 e.printStackTrace();
            } finally {
                 this.unlock();
            }
        }
    }
 }

park-unpark

 package tech.ityoung.study.demo.jvm.juc;
 ​
 import lombok.extern.slf4j.Slf4j;
 ​
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.locks.LockSupport;
 ​
 @Slf4j
 public class ConCrossExecutionDemo03 {
     public static void main(String[] args) throws InterruptedException {
         ParkConCrossExecutor executor = new ParkConCrossExecutor(5);
         List<Thread> threads = new ArrayList<>();
         Thread t1 = new Thread(() -> {
             executor.print("1", threads.get(1));
        }, "t1");
         Thread t2 = new Thread(() -> {
             executor.print("2", threads.get(2));
        }, "t2");
         Thread t3 = new Thread(() -> {
             executor.print("3", threads.get(0));
        }, "t3");
         threads.add(t1);
         threads.add(t2);
         threads.add(t3);
         t1.start();
         t2.start();
         t3.start();
         Thread.sleep(1000);
         LockSupport.unpark(t1);
    }
 }
 ​
 @Slf4j
 class ParkConCrossExecutor {
     private Integer loopNum;
 ​
     public ParkConCrossExecutor(Integer loopNum) {
         this.loopNum = loopNum;
    }
 ​
     public void print(String str, Thread next) {
         for (Integer i = 0; i < loopNum; i++) {
             LockSupport.park();
             log.info(str);
             LockSupport.unpark(next);
        }
    }
 }
赞(1) 打赏
未经允许不得转载:Stephen Young » 三种异步方式实现顺序打印
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏