控制多线程的打印顺序的两种方式

/*
需求是:有两个线程,一个线程打印1,一个线程打印2,先打印2再打印1
*/
(1)使用wait/notify

@Slf4j(topic = "c.PrintTest")
public class PrintTest {
    static final Object lock=new Object();
    static boolean t2runed=false;//表示t2是否运行过
    public static void main(String[] args) {
        //线程1继续执行的条件是看看t2是否已经打印,若条件不满足(t2没有打印)则进入等待,若它t2已经打印,则可以打印1
     Thread t1=new Thread(()->{
         synchronized (lock){
             while(!t2runed){
                 try{
                     lock.wait();
                 }catch (Exception e){
                     e.printStackTrace();
                 }

             }
         }
         log.debug("1");
     },"t1");
        Thread t2=new Thread(()->{
        synchronized (lock){
            log.debug("2");
            t2runed=true;
            lock.notify();
        }
        },"t2");

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

//分析:如果t1先执行,那t1先获得锁,然后它去判断t2是否打印了2,发现还没有打印,
//则进入等待队列中进行等待,此时它会释放锁,t2启动后想去执行会由于锁而被阻塞,当t1释放锁时
//它获得到锁后,它先打印2,然后将打印标记置为真,再去唤醒t1,让他打印1,释放锁,结束。
//
//如果t2先执行,它获得到锁,打印2,将打印标记置为true,notify,释放锁,t1再获取锁,判断打印标记,发现为真,
//直接打印1,释放锁,结束。

(2)使用park()和unpack()

@Slf4j(topic = "c.PrintTest2")
public class PrintTest2 {
    public static void main(String[] args) {
        Thread t1=new Thread(()->{
            LockSupport.park();
            log.debug("1");
        },"t1");
        t1.start();       
        
        new Thread(()->{
            log.debug("2");
            LockSupport.unpark(t1);
        },"t2").start();
    }
}

//分析,如果是t1先运行,它会先暂停,接着t2运行,打印2之后将t1唤醒,打印1
//如果是t2先运行,它先打印2,然后unpark(t1),相当于提前给t1补充好了干粮,当t1运行时,不会再暂停(相当于干粮充足)直接打印1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值