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

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

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();
	}
}
时间: 2024-10-19 13:12:51

一道经典的线程间通信的编程题的相关文章

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

经典笔试题: 1.自定义容器,提供新增元素(add)和获取元素数量(size)方法.2.启动两个线程.线程1向容器中新增10个数据.线程2监听容器元素数量,当容器元素数量为5时,线程2输出信息并终止. package com.gaopeng.programming.test2; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * 练习:使用wait,notif

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

经典笔试题: 1.自定义容器,提供新增元素(add)和获取元素数量(size)方法.2.启动两个线程.线程1向容器中新增10个数据.线程2监听容器元素数量,当容器元素数量为5时,线程2输出信息并终止. package com.gaopeng.programming.test2; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * 练习:使用Volatile实现

线程间通信和线程互斥

线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后在主线程刷新UI界面 视图布局我就不写了,大家自己来吧,线程间通信代码如下: #pragma mark - 添加响应方法触发创建子线程并加载数据 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

Java线程间通信之wait/notify

Java中的wait/notify/notifyAll可用来实现线程间通信,是Object类的方法,这三个方法都是native方法,是平台相关的,常用来实现生产者/消费者模式.先来我们来看下相关定义: wait() :调用该方法的线程进入WATTING状态,只有等待另外线程的通知或中断才会返回,调用wait()方法后,会释放对象的锁. wait(long):超时等待最多long毫秒,如果没有通知就超时返回. notify() : 通知一个在对象上等待的线程,使其从wait()方法返回,而返回的前

进程间通信与线程间通信

序 今天被问及进程间通信的问题,发现自己了解的并不够,所以,对此好好总结一番~ 操作系统的主要任务是管理计算机的软件.硬件资源.现代操作系统的主要特点是多用户和多任务,也就是程序的并行执行,windows如此linux也是如此.所以操作系统就借助于进程来管理计算机的软.硬件资源,支持多任务的并行执行.要并行执行就需要多进程.多线程.因此多进程和多线程间为了完成一定的任务,就需要进行一定的通信.而线程间通信又和进程间的通信不同.由于进程的数据空间相对独立而线程是共享数据空间的,彼此通信机制也很不同

关于eventfd,epoll,线程间通信小记

先介绍eventfd 1 #include<sys/eventfd.h> 2 int eventfd(unsigned int initval, int flags); 使用这个函数来创建一个事件对象,linux线程间通信为了提高效率,大多使用异步通信,采用事件监听和回调函数的方式来实现高效的任务处理方式(虽然会将逻辑变得复杂). linux内核会为这个事件对象维护一个64位的计数器(uint64_t).并在初始化时用传进去的initval来初始化这个计数器,然后返回一个文件描述符来代表这个事

java线程间通信

等待通知机制的实现 方法wait()的作用是使当前执行代码的线程进行等待,wait()方法是object类的方法,该方法的作用是将当前线程置入"预执行队列中",并且在wait()所在的代码行处停止执行,直到接到通知,或者被中断为止. 在调用wait()方法执行,线程需要先获得该对象的对象级别锁,也就是说,只能在同步方法,或者同步块中调用wait()方法,在执行wait()方法后,当前线程释放锁,在从wait()方法返回前,线程与其他线程竞争重新获得锁,如果调用wait()是没有持有适当

线程间通信与协作方式之——wait-notify机制

大家好,上篇文章为大家介绍了线程间通信和协作的一些基本方式,那这篇文章就来介绍一下经典的wait-notify机制吧. 什么是wait-notify机制? 想象一下有两个线程A.B,如果业务场景中需要这两个线程交替执行任务(比如A执行完一次任务后换B执行,B执行完后再换A执行这样重复交替),之前的基本通信方式只能让线程暂停一段指定时间,Join方法也无法做到这种交替执行的要求,那怎么办呢? 别急,针对这种场景java同样为我们提供了一种经典的线程通信方式--wait-notify机制,这里涉及到

Net线程间通信的异步机制

线程间通信 我们看下面的图 我们来看线程间通信的原理:线程(Thread B)和线程(Thread A)通信, 首先线程A 必须实现同步上下文对象(Synchronization Context), 线程B通过调用线程A的同步上下文对象来访问线程A,所有实现都是在同步上下文中完成的.线程B有两种方式来实现线程间的通信. 第一种:调用线程A的同步上下文对象,阻碍当前线程,执行红色箭头调用,直到黄色箭头返回(同步上下文执行完毕)才释放当前线程. (1->2->3->5) 第二种:调用线程A的