java 线程交互之wait/notify

众所周知java支持多线程,有多线程就必然会存在多线程的交互,交互方式有多种,比如通过共享数据,或者通过提供的锁信号量等等,这里通过用wait以及notify实现线程交互。

要用好线程的wait和notify就要首先了解一下线程的状态,线程的状态大致可以划分为一下几种,创建->就绪->运行->阻塞->销毁

一个线程通过new 到调用start完成了创建到就绪,这个之后就是等待cpu分配资源运行,阻塞的状态是发生在线程运行状态之后,发生线程阻塞的情况有很多种,这里简单的列举一下

1>锁阻塞

2>调用wait阻塞

3>调用join阻塞

4>调用sleep阻塞

当然线程也可以从运行状态返回到就绪状态,这个是通过调用Thread类的yeild方法实现的,这里简单说明一下,wait以及notify和notifyall是在超父类Object中提供的,也就是说属于类的

,而sleep/join/yeild是Thread这个类提供的,也即是属于线程的

从上可知,wait以及notify是只能用在对象锁上,不能和共享锁一起使用即只能和synchroized这个关键之一起使用,也就是说用wait和notify之前,必须先获得对象的锁,当调用wait的时候,

线程被放入对象监视器的等待队列里面,而且会释放锁,等待其他线程调用notify从锁对象监视器的等待队列里,取得一个线程执行,记着,synchronized是对象锁,就是说她要锁整个对象。

通过以上我们大致了解了,wait和notify的知识点,下面请看例子,简单的生产者消费者的例子

 1 public class Test {
 2
 3     private static List<Integer> queue = new ArrayList<>();
 4
 5
 6     /**
 7      * 生产者
 8      * @param n     void
 9      *
10      */
11     public synchronized void producer(int n){
12         System.out.println("insert data "+n);
13         queue.add(n);
14
15         if(queue.size()==1)
16             this.notify();
17     }
18
19     /**
20      * 消费者
21      * @return     int
22      *
23      */
24     public synchronized int consumer(){
25             try {
26                 if(queue.isEmpty())
27                     this.wait();
28             } catch (InterruptedException e) {
29                 e.printStackTrace();
30             }
31         int result = queue.get(0);
32         queue.remove(0);
33         return result;
34     }
35
36     public static void main(String[] args) {
37         final Test test = new Test();
38
39         Thread thread1 = new Thread(new Runnable() {//生产线程
40
41             @Override
42             public void run() {
43                 Random random = new Random();
44                 try {
45                     while(true){
46                         test.producer(random.nextInt(1000));
47                         Thread.sleep(2000);
48                     }
49                 } catch (InterruptedException e) {
50                     e.printStackTrace();
51                 }
52             }
53         });
54
55         Thread thread2 = new Thread(new Runnable() {//消费线程
56
57             @Override
58             public void run() {
59                 try {
60                     while(true){
61                         System.out.println("select data is "+test.consumer());
62                         Thread.sleep(1000);
63                     }
64                 } catch (InterruptedException e) {
65                     e.printStackTrace();
66                 }
67             }
68         });
69
70         thread1.start();
71         thread2.start();
72     }
73 }

以上是个人的理解,如有误的地方,欢迎大家批评指正,不胜感激

时间: 2024-10-02 22:32:47

java 线程交互之wait/notify的相关文章

Java线程通信——wait() 和 notify()

Object类中有关线程通信的方法有两个notify方法和三个wait方法,官方解释: void notify() Wakes up a single thread that is waiting on this object's monitor. void notifyAll() Wakes up all threads that are waiting on this object's monitor. String toString() Returns a string represent

JAVA线程交互

线程的运行都是独立的,但是存在多个线程需要同时访问共享的资源时,需要用到线程的同步(synchronized),就相当于在共享的对象资源上加了一把锁,每次只能一个线程获得对象锁.最简 单的例子:如卖电影票,几个窗口(线程)同时对电影票进行销售,彼此线程都是互斥的,每次只能一个线程去访问电影票(这个对象).但是也存在一种生产者-消费者的流程,这时需要用到线程的交互(wait()与notify()/notifyAll(),等待-唤醒),比如写个生产包子与卖包子的例子,每次生产包子到100个后就通知去

java 线程之间通信以及notify与notifyAll区别。

jvm多个线程间的通信是通过 线程的锁.条件语句.以及wait().notify()/notifyAll组成. 下面来实现一个启用多个线程来循环的输出两个不同的语句. package com.app.thread; import javax.swing.plaf.SliderUI;/** * 看出问题来 * @author Gordon * */public class LockDemo { public static void main(String[] args) {//  System.o

java 线程通信

java 线程通信使用wait notify 配合synchronized 当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态.当执行notify/notifyAll方法时,会唤醒一个处于等待该 对象锁 的线程,然后继续往下执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁. 如下代码: public class ThreadTest { //声明一个线程可视化的list集合 public static List<String> lis

Java线程:线程的交互

一.线程交互的基础知识 SCJP所要求的线程交互知识点需要从java.lang.Object的类的三个方法来学习: void notify()           唤醒在此对象监视器上等待的单个线程.  void notifyAll()           唤醒在此对象监视器上等待的所有线程.  void wait()           导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法. 当然,wait()还有另外两个重载方法: void w

JAVA线程间协作:wait.notify.notifyAll

JAVA的进程同步是通过synchronized()来实现的,须要说明的是,JAVA的synchronized()方法相似于操作系统概念中的相互排斥内存块.在JAVA中的Object类型中.都是带有一个内存锁的,在有线程获取该内存锁后.其它线程无法訪问该内存.从而实现JAVA中简单的同步.相互排斥操作. 明确这个原理.就能理解为什么synchronized(this)与synchronized(static XXX)的差别了.synchronized就是针对内存区块申请内存锁,thiskeywo

wait和notify实现的生产者消费者线程交互

public class ProductTest { public static void main(String args[]) { Repertory repertory=new Repertory(); new Thread(new Producer(repertory)).start(); new Thread(new Consumer(repertory)).start(); } } class Repertory{ private int product=0; public sync

Java线程中sleep()、wait()和notify()和notifyAll()、yield()、join()等方法的用法和区别

Java线程中sleep().wait()和notify()和notifyAll().suspend和resume().yield().join().interrupt()的用法和区别 从操作系统的角度讲,os会维护一个ready queue(就绪的线程队列).并且在某一时刻cpu只为ready queue中位于队列头部的线程服务. 但是当前正在被服务的线程可能觉得cpu的服务质量不够好,于是提前退出,这就是yield. 或者当前正在被服务的线程需要睡一会,醒来后继续被服务,这就是sleep. 

(转) Java线程同步阻塞, sleep(), suspend(), resume(), yield(), wait(), notify()

为了解决对共享存储区的访问冲突,Java 引入了同步机制.但显然不够,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个. 为解决访问控制问题,Java 引入阻塞机制.阻塞指的是暂停一个Java线程同步的执行以等待某个条件发生(如某资源就绪). sleep():允许指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间内进入阻塞状态,不能得到CPU 时 间,指定的时间一过,线程重新进入可执行状态.典型地,sleep() 被用在等待某个资源就绪的情