一道经典的线程间通信的编程题

Posted Trust_FreeDom

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道经典的线程间通信的编程题相关的知识,希望对你有一定的参考价值。

本来是看到另一篇博文中的题目,觉得博主实现的方式有点问题,故尝试自己实现,还望大家指教。

http://blog.csdn.net/u014039577/article/details/48623721

 

问题描述

启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5, 然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15. 接着再由线程1打印16,17,18,19,20....以此类推, 直到打印到75. 程序的输出结果应该为:

线程1: 1

线程1: 2

线程1: 3

线程1: 4

线程1: 5

线程2: 6

线程2: 7

线程2: 8

线程2: 9

线程2: 10

...

线程3: 71

线程3: 72

线程3: 73

线程3: 74

线程3: 75

 

实现代码:

public class WaitNotifyDemo1 {
	private int num; //输出数字
	private int runThreadNum; //当前运行线程编号
	
	public WaitNotifyDemo1(int num, int runThreadNum){
		this.num = num;
		this.runThreadNum = runThreadNum;
	}
	
	
	/**
	 * 打印线程
	 */
	static class PrintThread extends Thread{
		private int threadNum; //当前运行线程编号
		private WaitNotifyDemo1 demo; //锁对象
		
		public PrintThread(int threadNum, WaitNotifyDemo1 demo){
			this.threadNum = threadNum;
			this.demo = demo;
		}
		
		@Override
		public void run() {
			synchronized (demo) {
				try{
					for(int i=1; i<=5; i++){
						while(true){
							if(threadNum == demo.runThreadNum){
								break;
							}
							else{
								//如果当前线程不是接下来要运行的线程,进入等待池
								demo.wait(); 
							}
						}
						
						for(int j=1; j<=5; j++){
							System.out.println("线程"+threadNum+":"+(++demo.num));
						}
						
						demo.runThreadNum = demo.runThreadNum%3 +1; //计算之后运行的线程编号
						demo.notifyAll(); //唤醒所有等待池中的线程
					}
				}
				catch(Exception e){
					e.printStackTrace();
				}
			}
		}
	}
	
	
	public static void main(String[] args) {
		WaitNotifyDemo1 demo = new WaitNotifyDemo1(0,1);
		
		new PrintThread(1,demo).start();
		new PrintThread(2,demo).start();
		new PrintThread(3,demo).start();
	}
}

以上是关于一道经典的线程间通信的编程题的主要内容,如果未能解决你的问题,请参考以下文章

七. 多线程编程9.线程间通信

一道经典面试题:字符串在Java中如何通过“引用”传递

经典干货《Java 多线程编程核心技术》学习笔记及总结(中)

多线程经典面试题

经典笔试题:线程通信(使用Volatile实现线程间通信)

经典笔试题:线程通信(使用CountDownLatch实现线程间通信)