二、通过Condition的awiat和signal 前言: 在多线程中线程的执行顺序是依靠哪个线程先获得到CUP的执行权谁就先执行,虽然说可以通过线程的优先权进行设置,但是他只是CUP执行权的概率高点,但是也不一定必须先执行。在这种情况下如何保证线程按照一定的顺序进行执行,今天就来一个大总结,分别介绍一下几种方式。 一、通过Object的wait和notify 二、通过Condition的awiat和signal 三、通过一个阻塞队列 四、通过两个阻塞队列 五、通过SynchronousQueue 六、通过线程池的Callback回调 七、通过同步辅助类CountDownLatch 八、通过同步辅助类CyclicBarrier 一、通过Object的wait和notify 写一个测试了Test,加上main方法,在写一个内部类Man进行测试。main方法如下,他进行创建两个线程,传进去Runnable对象。 public static boolean flag = false; public static int num = 0; public static void main(String[] args) { Man man = new Man(); new Thread(() -> { man.getRunnable1(); }).start(); new Thread(() -> { man.getRunnable2(); }).start(); } getRunnable1和getRunnable2分别表示两个需要执行的任务,在两个线程中进行,方法1用于数据的生产,方法二用于数据的,数据的初始值为num = 0,为了保证生产和平衡需要使用wait和notify方法,这两个方法的使用必须是要加锁的,因此使用synchronized进行加锁使用,为了演示这个效果,我们加上一个sleep方法模拟处理时间,如下: public static class Man { public synchronized void getRunnable1() { for (int i = 0; i < 20; i++) { while (flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(“生产出:” + (++num) + “个”); flag = true; notify(); } } public synchronized void getRunnable2() { for (int i = 0; i < 20; i++) { while (!flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //模拟加载时间 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(“取出出:” + (num–) + “个”); System.out.println(“——————“); flag = false; notify(); } } } 分析它的加载流程,从方法1进行分析,由于flag的初始条件为false,所以方法1不进入等待,直接进行生产,生产完成成之后,更新flag的值为true,同时notify下一个方法2的wait方法,使其变为唤醒状态。这时候由于方法1加锁了,无法执行方法1其他部分,当方法1执行完毕,方法1才有可能执行,但是方法1的flag已经为true,进入到wait里面又处于阻塞状态,所以这时候只能执行方法2了。由于方法2被唤醒了,阻塞解除,接下来就数据,当完毕又再次让flag变为false,notify方法1解除阻塞,再次执行方法1,就这样不断的循环,保证了不同线程的有序执行,直到程序终止。 运行效果如下: 






2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/21149.html