JUC包多线程之线程有序执行

想让多个线程有序执行,必须提供它们之间的唤醒机制。下面以三个线程为例,有序打印自己的线程ID

Condition condition1 = lock.newCondition();  //代表线程1的唤醒

Condition condition2 = lock.newCondition();    //代表线程2的唤醒

Condition condition3= lock.newCondition();  //代表线程3的唤醒

同时需要一个Flag作为轮到它们各自执行的条件flag=1线程1执行,不等于1则线程1进入等待唤醒

代码:

  1 package xianchengtest;
  2
  3 import java.util.concurrent.locks.Condition;
  4 import java.util.concurrent.locks.Lock;
  5 import java.util.concurrent.locks.ReentrantLock;
  6
  7 public class TestABCAlternate {
  8
  9     public static void main(String[] args) {
 10         ABCAlternate as = new ABCAlternate();
 11         new Thread(new Runnable() {
 12
 13             @Override
 14             public void run() {
 15                 for (int i = 1; i <= 10 ;i++) {
 16                     as.loopA(i);
 17
 18                 }
 19             }
 20         },"A").start();
 21         new Thread(new Runnable() {
 22
 23             @Override
 24             public void run() {
 25                 for (int i = 1; i <= 10 ;i++) {
 26                     as.loopB(i);
 27
 28                 }
 29             }
 30         },"B").start();
 31         new Thread(new Runnable() {
 32
 33             @Override
 34             public void run() {
 35                 for (int i = 1; i <= 10 ;i++) {
 36                     as.loopC(i);
 37                     System.out.println("----------------------------------");
 38                 }
 39             }
 40         },"C").start();
 41
 42     }
 43
 44 }
 45
 46 class ABCAlternate{
 47     private int flag = 1;
 48     private Lock lock = new ReentrantLock();
 49     private Condition condition1 = lock.newCondition();
 50     private Condition condition2 = lock.newCondition();
 51     private Condition condition3 = lock.newCondition();
 52
 53     public void loopA(int totaloop) {
 54         lock.lock();
 55
 56         try {
 57             //判断
 58             if(flag != 1) {
 59                 try {
 60                     condition1.await();
 61                 } catch (InterruptedException e) {
 62                 }
 63             }
 64             //打印
 65             for (int i = 1; i <= 1; i++) {
 66                 System.out.println(Thread.currentThread().getName() +"\t"+ i+ "\t" + totaloop);
 67             }
 68             //唤醒
 69             flag = 2 ;
 70             condition2.signal();
 71         } finally {
 72             lock.unlock();
 73         }
 74     }
 75     public void loopB(int totaloop) {
 76         lock.lock();
 77
 78         try {
 79             //判断
 80             if(flag != 2) {
 81                 try {
 82                     condition2.await();
 83                 } catch (InterruptedException e) {
 84                 }
 85             }
 86             //打印
 87             for (int i = 1; i <= 1; i++) {
 88                 System.out.println(Thread.currentThread().getName() +"\t"+ i+ "\t" + totaloop);
 89             }
 90             //唤醒
 91             flag = 3 ;
 92             condition3.signal();
 93         } finally {
 94             lock.unlock();
 95         }
 96     }
 97     public void loopC(int totaloop) {
 98         lock.lock();
 99
100         try {
101             //判断
102             if(flag != 3) {
103                 try {
104                     condition3.await();
105                 } catch (InterruptedException e) {
106                 }
107             }
108             //打印
109             for (int i = 1; i <= 1; i++) {
110                 System.out.println(Thread.currentThread().getName() +"\t"+ i+ "\t" + totaloop);
111             }
112             //唤醒
113             flag = 1 ;
114             condition1.signal();
115         } finally {
116             lock.unlock();
117         }
118     }
119
120
121 }

原文地址:https://www.cnblogs.com/blog-of-zxf/p/11126939.html

时间: 2024-11-09 03:59:22

JUC包多线程之线程有序执行的相关文章

Java多线程,线程交替执行

两个线程,一个打印1-100的奇数,一个打印1-100的偶数:要求:线程1打印5个之后,线程2开始打印,线程2打印5个之后,线程1再开始打印,以此循环. Code: package com.qhong; public class Main { /* * 两个线程,一个打印1-100的奇数,一个打印1-100的偶数:要求:线程1打印5个之后,线程2开始打印,线程2打印5个之后,线程1再开始打印,以此循环. */ private static int state = 1; private stati

Java多线程 -- JUC包源码分析11 -- ThreadPoolExecutor源码分析

在JUC包中,线程池部分本身有很多组件,可以说是前面所分析的各种技术的一个综合应用.从本文开始,将综合前面的知识,逐个分析线程池的各个组件. -Executor/Executors -ThreadPoolExecutor使用介绍 -ThreadPoolExecutor实现原理 –ThreadPoolExecutor的中断与优雅关闭 shutdown + awaitTermination –shutdown的一个误区 Executor/Executors Executor是线程池框架最基本的几个接

Java多线程之后台线程不执行finally

后台线程不执行finally package wzh.daemon; import java.util.concurrent.TimeUnit; class ADaemon implements Runnable { @Override public void run() { try { System.out.println("Starting ADaemon"); TimeUnit.SECONDS.sleep(1); } catch (Exception e) { System.ou

Concurrent包总结——线程任务执行框架

一 Executor接口 Executor接口的对象是一种执行任务的方式.它能够使提交的任务和执行任务的线程的管理解耦.我们通常用Executor来代替new一个Thread对象来执行任务.这样可以省略底层线程的管理细节. 例如: executor.excute(new RunnableTask()); concurrent包中提供了比较常用的Executor的实现,这些实现类都实现了一个更加灵活的类ExecutorService.而ThreadPoolExecutor则提供了一个可扩展的线程池

多线程之美4一 线程池执行原理浅析

目录结构 引言 一.线程池工作流程图 二.线程池的运行原理 三.线程池的7个参数 四.常用4个阻塞队列 五.四个拒绝策略语义以及测试用例 六.Executors工具类 6.1. Executors提供的三种线程池 6.2 实际开发中应该怎样设定合适线程池? 七.线程池提交任务的2种 八.总结 引言 ? 我们为什么要使用线程池,它可以给我们带来什么好处?要想合理使用线程池,我们需要对线程池的工作原理有深入的理解和认识,让我们一起来看看吧. 好处: ? 1.处理响应快,不用每次任务到达,都需要等待初

JAVA多线程之当一个线程在执行死循环时会影响另外一个线程吗?

一,问题描述 假设有两个线程在并发运行,一个线程执行的代码中含有一个死循环如:while(true)....当该线程在执行while(true)中代码时,另一个线程会有机会执行吗? 二,示例代码(代码来源于互联网) 1 public class Service { 2 Object object1 = new Object(); 3 4 public void methodA() { 5 synchronized (object1) { 6 System.out.println("methodA

十一、JUC包中的锁

JUC,即java.util.concurrent. 悲观锁和乐观锁 悲观锁和乐观锁是一种思想. 悲观锁,持有一种悲观的态度,认为会出现很坏的情况,所以,先做预防措施.独占锁是一种悲观锁,synchronized就是一种独占锁. 而乐观锁,则是持有一种持有种乐观的态度,认为不会出现什么问题,有问题了再说. 对于常用多线程编程的人估计知道,在jdk5之前,在多线程编程的时候,为了保证多个线程对一个对象同时进行访问时,我们需要加同步锁synchronized,保证对象的在使用时的正确性,但是加锁的机

JUC包中的锁框架

JUC包中的锁,包括:Lock接口,ReadWriteLock接口,LockSupport阻塞原语,Condition条件,AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer三个抽象类,ReentrantLock独占锁,ReentrantReadWriteLock读写锁.由于CountDownLatch,CyclicBarrier和Semaphore也是通过AQS来实现的:因此

JUC包中的CountDownLatch源码实现分析

CountDownLatch是JUC包中提供的线程同步工具,使用CountDownLatch可以实现一个或多个线程等待直到一组操作在其他线程中被执行完成. CountDownLatch基于AQS实现,代码不多,所以很好分析.本文只分析CountDownLatch实现, 关于AQS的实现在另外一篇文章中叙述. 下面是CountDownLatch的类图: 接下来贴上来CountDownLatch的源码: public class CountDownLatch { private static fin