首页 > 编程语言 >java线程之wait、notifyAll

java线程之wait、notifyAll

时间:2023-04-26 20:02:00浏览次数:44  
标签:java Thread thread notifyAll 线程 坐下 座位 main pool


wait、notifyAll是线程之间用来通信的,设计模式里的观察者模式。

例子,上课前,同学在玩,一个同学观察老师是不是来了,如果来了,叫其他同学坐好。

package com.concurrent;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import junit.framework.TestCase;

public class TestWaitNotify extends TestCase {
	static final CountDownLatch cdl = new CountDownLatch(31);

	public void testWaitNotify() {
		Monitor monitor = new Monitor();
		ExecutorService executorService = Executors.newFixedThreadPool(31);

		for (int i = 0; i < 30; i++) {
			Student student = new Student(monitor);
			monitor.addClassMate(student);
			executorService.execute(student);
		}
		executorService.execute(monitor);

		System.out.println(Thread.currentThread() + "老师还没来");
		monitor.setTeacherIsComing(true);
		System.out.println(Thread.currentThread() + "老师来了");

		try {
			cdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		executorService.shutdown();
	}

	static class Student implements Runnable {
		private Monitor monitor;

		Student() {

		}

		Student(Monitor monitor) {
			this.monitor = monitor;
		}

		@Override
		public void run() {
			synchronized (monitor) {
				while (!monitor.isTeacherIsComing()) {
					try {
						monitor.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println(Thread.currentThread() + "回到自己座位,坐下");
				cdl.countDown();
			}
		}
	}

	static class Monitor extends Student {
		private boolean teacherIsComing = false;

		private Set<Student> classMates = new HashSet<Student>();

		@Override
		public void run() {
			synchronized (this) {
				while (!teacherIsComing) {
					System.out.println(Thread.currentThread() + "看老师是否来了");
				}
				notifyAll();
				cdl.countDown();
			}
		}

		public boolean isTeacherIsComing() {
			return teacherIsComing;
		}

		public void setTeacherIsComing(boolean teacherIsComing) {
			this.teacherIsComing = teacherIsComing;
		}

		public void addClassMate(Student student) {
			classMates.add(student);
		}
	}
}



运行一下:

Thread[main,5,main]老师还没来
Thread[main,5,main]老师来了
Thread[pool-1-thread-28,5,main]回到自己座位,坐下
Thread[pool-1-thread-29,5,main]回到自己座位,坐下
Thread[pool-1-thread-26,5,main]回到自己座位,坐下
Thread[pool-1-thread-24,5,main]回到自己座位,坐下
Thread[pool-1-thread-22,5,main]回到自己座位,坐下
Thread[pool-1-thread-27,5,main]回到自己座位,坐下
Thread[pool-1-thread-25,5,main]回到自己座位,坐下
Thread[pool-1-thread-23,5,main]回到自己座位,坐下
Thread[pool-1-thread-20,5,main]回到自己座位,坐下
Thread[pool-1-thread-21,5,main]回到自己座位,坐下
Thread[pool-1-thread-19,5,main]回到自己座位,坐下
Thread[pool-1-thread-18,5,main]回到自己座位,坐下
Thread[pool-1-thread-17,5,main]回到自己座位,坐下
Thread[pool-1-thread-16,5,main]回到自己座位,坐下
Thread[pool-1-thread-14,5,main]回到自己座位,坐下
Thread[pool-1-thread-15,5,main]回到自己座位,坐下
Thread[pool-1-thread-12,5,main]回到自己座位,坐下
Thread[pool-1-thread-13,5,main]回到自己座位,坐下
Thread[pool-1-thread-10,5,main]回到自己座位,坐下
Thread[pool-1-thread-11,5,main]回到自己座位,坐下
Thread[pool-1-thread-9,5,main]回到自己座位,坐下
Thread[pool-1-thread-8,5,main]回到自己座位,坐下
Thread[pool-1-thread-7,5,main]回到自己座位,坐下
Thread[pool-1-thread-6,5,main]回到自己座位,坐下
Thread[pool-1-thread-4,5,main]回到自己座位,坐下
Thread[pool-1-thread-5,5,main]回到自己座位,坐下
Thread[pool-1-thread-3,5,main]回到自己座位,坐下
Thread[pool-1-thread-2,5,main]回到自己座位,坐下
Thread[pool-1-thread-1,5,main]回到自己座位,坐下
Thread[pool-1-thread-30,5,main]回到自己座位,坐下




标签:java,Thread,thread,notifyAll,线程,坐下,座位,main,pool
From: https://blog.51cto.com/u_1002776/6228782

相关文章

  • java之用volatile和不用volatile的区别
    在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。 要解决这个问题,只需要像在本程序中的这样,把该变量......
  • java流程控制
    scanner创建一个新的扫描器对象,用于接受键盘数据Scannerscanner=newScanner(System.in);//使用next方式接收Stringsrt=scanner.next();//使用nextLine方式接收Stringsrt=scanner.nextLine();next():一定要读取到有效字符后才可以结束输入对输入有效字符之前......
  • 深入java虚拟机 - 垃圾收集 - 引用计数收集器
         引用计数是垃圾收集的早期策略。在这种方法中,堆中每一个对象都有一个引用计数。一个对象被创建了,并且指向该对象的引用被分配给一个变量,这个对象的引用计数被置为1。当任何其他变量被赋值为对这个对象的引用时,计数加1。当一个对象的引用超过了......
  • java 多线程 synchronized
    程序1:packagetestsynchronized;publicclassThread1implementsRunnable{ @Override publicvoidrun(){ synchronized(this){ for(inti=0;i<10;i++){ System.out.println(Thread.currentThread().getName() +"synchronizedloo......
  • java 一些奇怪的笔试题
    例1:packagecom.test;publicclassTest1{ publicvoidtestExit(){ try{ System.exit(0); }finally{ System.out.println("testExit"); } } publicvoidtestReturn(){ try{ return; }finally{ System.out.println("......
  • docker启动rabbitMQ,通过java创建交换机、队列、绑定
    通过docker启动rabbitMQdockerrun-d--namerabbitmq-p5671:5671-p5672:5672-p4369:4369-p25672:25672-p15671:15671-p15672:15672rabbitmq:management  将其修改为自启动:dockerupdaterabbitmq--restart=always  以下为通过java代码进行创建交换机......
  • 【Java设计模式】装饰者设计模式
    目录1.装饰者模式(Wrapper)概念2.装饰者是什么?3.装饰者设计模式-参与者3.1组成3.1Demo1.Component(抽象构件)2.ConcreteComponent(具体构件)3.Decorator(抽象装饰类)4.ConcreteDecorator(具体装饰类)5.Test类:3.2总结4.JDK源码中的装饰者设计模式扩展:开闭原则1.装饰者模式(Wra......
  • VScode 创建Java项目
    1.点击view找到命令行输入java(ctrl+shift+P)src:一般是自己写的源代码的文件lib:外部引用库等其他的内容bin:二进制程序,用以存放未来的编译文件等  ......
  • javascript操作cookie
    functionsetCookie(name,value){varDays=30;varexp=newDate();exp.setTime(exp.getTime()+Days*24*60*60*1000);document.cookie=name+"="+escape(value)+";expires="+exp.toGMTString();......
  • java 多线程的start()和run()的理解
    run()方法中是各个线程要执行的具体内容。所以当一个线程直接调用run()时那么直接开始执行方法体,这是在main线程中的多个线程只能时按照顺序的等待前面的线程结束run()方法的执行。而调用start方法只是线程进入准备阶段(Ready),并没有真正执行,这需要JVM进行分配时间片进行轮转线程执......