如何让 10 个线程按照顺序打印 0123456789

7 篇文章 0 订阅

如何让 10 个线程按照顺序打印 0123456789?

  1. 设定一个 orderNum,每个线程执行结束之后,更新 orderNum,指明下一个要执行的线程。并且唤醒所有的等待线程。

  2. 在每一个线程的开始,要 while 判断 orderNum 是否等于自己的要求值!!不是,则 wait,是则执行本线程。

                                     while(顺序不匹配){
                                          wait
                                      }
                                         update orderNum 

import java.util.ArrayList;
import java.util.List;
public class thredSortedPrint {
    public static void main(String[] args) {
        //创建10个线程
        List<myThread> list = new ArrayList<myThread>();
        for(int i=10;i>0;i--){
            myThread thread = new myThread(i);
            thread.start();
        }
    }
    //创建一个内部静态类
    static class myThread extends Thread{
        public int Num;
        static int orderNum = 1;
        //创建一个静态的object类作为共同的互斥锁资源
        static final Object object = new Object();
        public myThread (int num){
            this.Num = num;
        };
        @Override
        public void run(){
            synchronized (object){
                //顺序不匹配则等待,并让出锁资源
                while(Num != orderNum){
                    try {
                        System.out.println(Thread.currentThread().getName()+":wait");
                        //锁是object,用object.wait(),当前线程被阻塞,进入等待队列,同时释放互斥锁object
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //匹配则输出打印,更新orderNum,并通知所有线程。
                System.out.println(Thread.currentThread().getName()+":"+Num);
                orderNum++;
                //通知互斥锁的等待队列
                object.notifyAll();
            }
        }
    }
}

运行并查看结果,如下。

Thread-0:wait
Thread-1:wait
Thread-3:wait
Thread-4:wait
Thread-7:wait
Thread-8:wait
Thread-2:wait
Thread-6:wait
Thread-5:wait
Thread-9:1
Thread-5:wait
Thread-6:wait
Thread-2:wait
Thread-8:2
Thread-7:3
Thread-4:wait
Thread-3:wait
Thread-1:wait
Thread-0:wait
Thread-2:wait
Thread-6:4
Thread-5:5
Thread-2:wait
Thread-0:wait
Thread-1:wait
Thread-3:wait
Thread-4:6
Thread-3:7
Thread-1:wait
Thread-0:wait
Thread-2:8
Thread-0:wait
Thread-1:9
Thread-0:10

补充:如果通知等待队列的语句改成  object.notify(),可能会导致所有等待的线程都处于等待状态,应该被唤醒的线程没有机会再被唤醒。如下,启动的线程争抢CPU资源,如果打印顺序刚好匹配,则执行并随机通知一个处于等待队列的线程。但是若所有线程都启动了,除去已执行完的线程,剩下的都在队列里,这时候Thread-8执行完后随机通知,被通知到恰好是Thread-3,而此时应该被通知的是Thread-7。Thread-3因打印顺序不匹配,进入等待队列。这时候剩余所有线程都在队列里,也就没有线程会被通知并执行了,形成了活锁。

//通知互斥锁的等待队列
   object.notify();

 

Thread-2:wait
Thread-3:wait
Thread-7:wait
Thread-6:wait
Thread-1:wait
Thread-5:wait
Thread-9:1
Thread-2:wait
Thread-0:wait
Thread-4:wait
Thread-8:2
Thread-3:wait

 

运用jconsole工具查看线程执行情况 : https://blog.csdn.net/Henry_Lin_Wind/article/details/103408654 

剩余的线程全部在等待,但是并没有死锁,所以要慎重使用notify()。

那什么时候可以使用 notify() 呢?需要满足以下三个条件:
1. 所有等待线程拥有相同的等待条件;
2. 所有等待线程被唤醒后,执行相同的操作;
3. 只需要唤醒一个线程。
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值