注意:这些方法属于Object,而不属于Thread。
每一个对象除了有一个锁之外,还有一个等待队列(wait set),当一个对象刚创建的时候,他的等待队列是空的。
我们可以利用这些方法来解决“生产者和消费者的问题”。
wait方法呢,是在当前线程锁住对象的锁后,才调用该对象的wait方法的。即在同步代码块中或者同步方法中进行调用的。调用后,该对象的等待队列中就有了一个所在线程,那个线程进入等待状态,此时,只有该对象调用notify方法,才可以把那个线程从队列里面拿出来,使这个线程成为可运行线程。
notifyAll方法就是把该对象等待队列里面的所有线程唤醒,成为可运行线程。
生产者和消费者问题的简单实现:
public class ProductorConsumerProblem {
/**
* @param args
*/
public static void main(String[] args) {
ThreadQueue queue=new ThreadQueue();
Productor productor=new Productor(queue);
Consumer consumer=new Consumer(queue);
productor.start();
consumer.start();
}
}
/*生产者类*/
class Productor extends Thread{
ThreadQueue queue;//等待队列
public Productor(ThreadQueue q){
queue=q;
}
public void run(){
for(int i=1;i<10;i++){
queue.put(i);//把数据放入等待队列中
System.out.println("Productor puts "+i);
}
}
}
class Consumer extends Thread{
ThreadQueue queue;
public Consumer(ThreadQueue q){
queue=q;
}
public void run(){
for(int i=1;i<10;i++){
System.out.println("Consumer gets "+queue.get());//从等待队列中取出数据并显示
}
}
}
class ThreadQueue{
int value;
boolean isFull=false;//false表示是空的
//下面的get和put都是用的是this这个监视器,所以可用notify和wait进行等待与唤醒
public synchronized void put(int i){
if(!isFull){//如果队列是空的,那么就放入数据,把队列的标志设为true(非空),然后调用notify方法,唤醒get的wait
this.value=i;
isFull=true;
notify();//当这个是第一次调用时等待队列里面没有等待的线程,那是不是要判断等待对列是否为空才判断执不执行呢,没必要,因为这个耗费不大,就相当于多执行一条语句,所以没必要判断,如果要写判断语句,那么代码还复杂些,所以这个影响不大的情况下,我们没必要判断。
}
try{
wait();//如果队列是非空的,那么就不要放入数据,就处于等待,一直等待消费者取走数据并调用notify方法
}catch(Exception e){
e.printStackTrace();
}
}
public synchronized int get(){
if(!isFull){
try{
wait();//如果队列是空的,那么就等待,不能取数据
}catch(Exception e){
e.printStackTrace();
}
}
notify();//如果非空,那么取走数据并调用notify方法唤醒put的等待,设置变量为空。注意,因为return后方法就不再继续了,所以要在return之前设置要做的事
isFull=false;
return value;
}
}
如果一个类是线程安全的,那么我们编写线程来调用那个类的方法等的时候,不会出现不同步,死锁等问题,我们要让类是安全的,可以被多线程调用,我们在那个类的方法或者代码块上就要加上关键字synchronized等处理线程同步等安全问题。这些是类设计者要考虑的问题,比如消费者和生产者那个问题中的ThreadQueue就要考虑线程安全问题。所以,设计类是很重要的,比如要有封装性,如果可以多线程访问,要考虑线程安全问题等等。
分享到:
相关推荐
源码—Java多线程5—死锁和wait notify notifyAll
在Java中,`wait()`, `notify()`, 和 `notifyAll()` 是Java Object类的三个方法,它们在实现线程间通信和协作时扮演着关键角色。这些方法主要用于解决线程等待和唤醒的问题,是基于Java Monitor(监视器)模型的。 ...
Java 中Object的wait() notify() notifyAll()方法使用 在Java并发编程中,Object的wait()、notify()和notifyAll()方法是非常重要的概念,这三个方法都是Object类的方法,可以认为任意一个Object都是一种资源(或者...
wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。 在 Java 中可以用 wait、notify 和 notifyAll 来实现...
Java多线程中wait、notify、notifyAll使用详解 Java中多线程编程中,wait、notify、notifyAll三个方法是非常重要的,它们都是Object对象的方法,用于线程之间的通信。下面我们将详细介绍这三个方法的使用和作用。 ...
当其他线程调用同一个对象的 `notify()` 或 `notifyAll()` 方法时,等待线程有机会重新获得锁并继续执行。需要注意的是,调用 `wait()` 方法必须在 `synchronized` 块或方法中进行,否则会抛出 `...
wait()、notify()和notifyAll()方法2---马克-to-win java视频
wait方法是Object类的一个方法,用于让当前线程进入等待状态,直到其他线程调用notify或notifyAll方法来唤醒它。在wait方法中,当前线程会释放它所占有的锁,并进入等待状态。wait方法可以带有参数,指定等待的时间...
10. HashMap什么样的类适合作为键String最为常见,因为String对象不可变,且重写了equals和hashcode方法。...sleep可在任意地方使用,wait notify notifyAll只能在synchronized块\方法中使用。sleep必须捕获异常
wait()、notify()和notifyAll()方法1---马克-to-win java视频
`wait()`、`notify()`和`notifyAll()`是Java中的三个关键字,它们属于Object类的方法,主要用于线程间的通信,尤其在实现生产者消费者模式时发挥着重要作用。本文将深入探讨这些方法以及如何在实际场景中应用它们。 ...
Java wait和notifyAll实现简单的阻塞队列 在 Java 中,wait 和 notifyAll 是两个非常重要的方法,它们都是在 Object 类中声明的,用于实现线程之间的通信和同步。wait 方法会使调用线程进入等待状态,并释放所持有...
`wait()` 方法会让当前持有锁的线程进入等待状态,释放锁,直到其他线程调用 `notify()` 或 `notifyAll()` 唤醒它。`notify()` 则会随机选择一个等待在该对象监视器上的线程并唤醒它,而 `notifyAll()` 则会唤醒所有...
Java中的`wait()`, `notify()`, 和 `notifyAll()` 是多线程编程中的关键工具,它们用于在并发环境中协调线程间的交互。这些方法都定义在`java.lang.Object`类中,因为它们与对象的监视器(monitor)概念密切相关。...
文章目录1 wait、notify、notifyAll简单介绍1.1 使用方法 + 为什么不是Thread类的方法1.2 什么时候加锁、什么时候释放锁?1.3 notify、notifyAll的区别2 两个比较经典的使用案例2.1 案例1 — ABCABC。。。三个线程...
标题和描述概述的知识点主要集中在Java的多线程机制中,特别是`wait`和`notify`方法在同步锁中的应用。这些方法对于控制线程之间的交互至关重要,尤其是在资源有限或需要确保数据一致性的情况下。 ### Java同步锁...
本文将深入探讨`wait`、`notify`以及`notifyAll`这三个关键字的使用及其背后的原理,帮助你理解如何在实际编程中有效地利用它们来解决线程同步问题。 首先,我们需要了解Java中的对象锁。每个Java对象都有一个内置...
本文将深入探讨Java中的wait()、notify()和notifyAll()方法,以及synchronized关键字和原子操作在多线程环境中的应用。 1. **wait()方法**: - wait()是Object类的一个方法,它的作用是让当前线程暂停执行并释放它...
Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll) Java多线程基础中的线程等待与唤醒是一种常见的线程协作机制,通过wait()、notify()和notifyAll()方法来实现线程之间的同步和通信。在本节中,我们将...
Java中的`notify`和`notifyAll`是多线程编程中的关键方法,它们用于线程间的通信,特别是在处理同步机制时。这两个方法都是在`Object`类中定义的,因此可以应用于任何Java对象。 首先,我们需要理解Java的同步机制...