Java线程间的通信(Object中的wait(),Thread中的join(),CountDownLatch中的await()/countDown(),CyclicBarrier中await())

多个线程协同工作来完成某个任务,涉及到线程间通信

如何让两个线程一次执行?

private static void demo1(){

	Thread A = new Thread(new Runnable(){
		@Override
		public void run(){
			printlNumber("A");
		}
	});

	Thread B = new Thread(new Runnable(){
		@Override
		public void run(){
			printNumber("B");
		}
	});

	A.start();
	B.start();
}
private static void printNumber(String threadName) {  
    int i=0;  
    while (i++ < 3) {  
        try {  
            Thread.sleep(100);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println(threadName + " print: " + i);  
    }  
}  

Java线程间的通信(Object中的wait(),Thread中的join(),CountDownLatch中的await()/countDown(),CyclicBarrier中await())_第1张图片

如何让两个线程按照指定方式有序交叉运行?

/**
	A打印1后,B打印1,2,3
	A继续打印2,3

	A 1, B 1, B 2, B 3, A 2, A 3 
	
	利用Object.wait()和Object.notify()两个方法执行
*/
private static void demo(){
	
	Object lock = new Object();

	Thread A = new Thread(new Runnable(){
		@Override
		public void run(){
		
			synchronized(lock){
				System.out.println("A 1");
				try{
					lock.wait();
				} catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  

				System.out.println("A 2");  
                System.out.println("A 3"); 		
			}
		}
	});

	Thread B = new Thread(new Runnable(){
		@Override
		public void run(){
			
			synchronized(lock){
				System.out.println("B 1");  
                System.out.println("B 2");  
                System.out.println("B 3");  
                lock.notify(); 
			}
		}
	});
	A.start();
	B.start();
}

Java线程间的通信(Object中的wait(),Thread中的join(),CountDownLatch中的await()/countDown(),CyclicBarrier中await())_第2张图片

四个线程A B C D,其中D要等到A B C全部执行完毕后才执行,而且A B C 是同步运行的

/**
	B在A全部打印完后再开始打印,利用thread.join()
*/
private static void demo(){
	
	Thread A = new Thread(new Runnable{
		
		@Override
		public void run(){
			printNumber("A");
		}
	});

	Thread B = new Thread(new Runnable(){
		
		@Override
		public void run(){
			System.out.println("B 开始等待 A");
			try{
				A.join();
			}catch(InterruptedException e){
				e.printStackTrace(); 
			}
			printNumber("B");
		}
	});

	B.start();
	A.start();
}

Java线程间的通信(Object中的wait(),Thread中的join(),CountDownLatch中的await()/countDown(),CyclicBarrier中await())_第3张图片

/**
	A B C 三个线程同时运行,各自独立运行完后通知 D;对 D 而言,只要 A B C 都运行完了,D 再开始运行。
	CountedownLatch实现
*/
private static void runDAfterABC(){
	
	int worker = 3;
	CountDownLatch countDownLatch = new CountDownLatch(worker); //创建计数器,初始值为3

	new Thread(new Runnable(){
		
		@Override
		public void run(){
		
			System.out.println("D is waiting for other three threads");
			try{
				//D线程进入等待状态,直到计数值变为0
				countDownLatch.await("All done, D starts working");
				System.out.println();
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}).start();

	for(char threadName='A';threadName <='C';threadName++){
		final String tN = String.valueOf(threadName);
		new Thread(new Runnable(){
			
			@Override
			public void run(){
				System.out.println(tN + " is working");
				try{
					Thread.sleep(100);
				}catch(Excption e){
					 e.printStackTrace();
				}
				System.out.prinltn(tN + " finished");
				//其他线程调用,该方法将计数值减1,直到减到0,等待线程继续执行
				countDownLatch.countDown(); 
			}
		}).start();
	}
}

三个运动员各自准备,等到三个都准备好,再一起跑

上面的 CountDownLatch 可以用来倒计数,但当计数完毕,只有一个线程的 await() 会得到响应,无法让多个线程同时触发。

private static void runABCWhenAllReady(){
	
	//创建一个公共的CyclicBarrier对象,设置同时等待的线程数为3
	int runner = 3;
	CyclicBarrier cyclicBarrier = new CyclicBarrier(runner);

	final Random random = new Random();
	for(char runnerName='A';runnerName<='C';runnerName++){
		final String rN = String.valueOf(runnerName);
		
		new Thread(new Runnable(){
		
			long prepareTime = random.nextInt(10000) + 100;
			System.out.println(rN + " is preparing for time: " + prepareTime);  
			try{
				Thread.sleep(prepareTime);
			}catch(Exception e){
				e.printStackTrace();  
			}

			try{
				System.out.println(rN + " is prepared, waiting for others");  
                cyclicBarrier.await(); // 当前运动员准备完毕,等待别人准备好
			}catch(InterruptedException e){
				e.printStackTrace(); 
			}catch (BrokenBarrierException e) {  
                e.printStackTrace();  
            }  
            System.out.println(rN + " starts running"); // 所有运动员都准备好了,一起开始跑
		}).start();
	}
}

Java线程间的通信(Object中的wait(),Thread中的join(),CountDownLatch中的await()/countDown(),CyclicBarrier中await())_第4张图片

子线程完成某件任务后,把得到的结果回传给主线程

FutureTask配合Callable使用,get方法会阻塞主线程

/**
	子线程去计算从 1 加到 100,并把算出的结果返回到主线程
*/
private static void doTaskWithResultInWorker(){
	
	Callable<Integer> callable = new Callable<Integer>(){
		
		@Override
		public Integer call() throws Exception{
			
			System.out.println("Task starts");  
            Thread.sleep(1000);  
            int result = 0;  
            for (int i=0; i<=100; i++) {  
                result += i;  
            }  
            System.out.println("Task finished and return result");  
            return result;  
		}
	};

	FutureTask<Integer> futureTask = new FutureTask<>(callable);
	new Thread(futureTask).start();

	try{
		System.out.println("Before futureTask.get()");  
        System.out.println("Result: " + futureTask.get()); //主线程调用 futureTask.get() 方法时阻塞主线程 
        System.out.println("After futureTask.get()"); 
	} catch (InterruptedException e) {  
        e.printStackTrace();  
    } catch (ExecutionException e) {  
        e.printStackTrace();  
    }  
}

Java线程间的通信(Object中的wait(),Thread中的join(),CountDownLatch中的await()/countDown(),CyclicBarrier中await())_第5张图片

你可能感兴趣的:(java,开发语言,线程通信)