wait()、notify()、notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态。
这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。
如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。打个比喻就是
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。
wait和notify区别、理解
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.
译:唤醒在此对象监视器上等待的所有线程
void wait( )
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll( ) method for this object.
译:导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法
void wait(long timeout)
Causes the current thread to wait until either another thread invokes the notify( ) method or the notifyAll( ) method for this object, or a specified amount of time has elapsed.
译:导致当前的线程等待,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者指定的时间过完。
void wait(long timeout, int nanos)
Causes the current thread to wait until another thread invokes the notify( ) method or the notifyAll( ) method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.
译:导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法,或者其他线程打断了当前线程,或者指定的时间过完。
上面是官方文档的简介,引用文章源:https://blog.csdn.net/m0_38144897/article/details/79543790
(
死锁指两个或两个以上的线程为了使用某个临界资源而无限制地等待下去。
死锁出现的最基本原因还是逻辑处理不够严谨,所以一般需要修改程序逻辑才能很好的解决死锁问题
)
其中wait方法有三个over load方法:
wait()
wait(long)
wait(long,int)
wait方法通过参数可以指定等待的时长。如果没有指定参数,默认一直等待直到被通知。
下面是在培训机构学习的关于此知识点的例子,个人觉得理解起来非常舒服。
代码如下
package
com.demo;
import
java.util.ArrayList;
import
java.util.List;
class
Apple {
public
final
String
name
=
"
苹果
"
;
}
//
装苹果的仓库
class
Warehouse {
//
仓库大小
public
static
final
int
SIZE
= 10;
public
List<Apple>
list
=
new
ArrayList<Apple>( );
//
增加苹果
public
synchronized
void
add() {
if
(
this
.
list
.size()<Warehouse.
SIZE
) {
list
.add(
new
Apple());
System.
out
.println(
"
生产者生产了
1
个现
"
+
list
.size()+
"
个
"
);
notifyAll();
//
让
wait
的不再
wait,
自已继续,即让
wait
的线程来与自己竞争
}
else
{
try
{
//System.out.println("
仓库满了,生产者等
...");
this
.wait();
}
catch
(InterruptedException
e
) {
e
.printStackTrace();
}
}
}
//
减少苹果
public
synchronized
void
reduce() {
if
(
this
.
list
.size()>0) {
list
.remove(
list
.size()-1);
System.
out
.println(
"
消费者消费了
1
个现
"
+
list
.size()+
"
个
"
);
notifyAll();
}
else
{
try
{
//System.out.println("
一仓库空了,消费者等
...");
this
.wait();
}
catch
(Exception
e
) {
e
.printStackTrace();
}
}
}
}
//
生产者
class
ProducerThread
extends
Thread {
private
Warehouse
warehouse
;
public
ProducerThread(Warehouse
warehouse
) {
this
.
warehouse
=
warehouse
;
}
@Override
public
void
run() {
while
(
true
) {
this
.
warehouse
.add();
try
{
Thread.
sleep
(400);
}
catch
(InterruptedException
e1
) {
e1
.printStackTrace();
}
}
}
}
//
消费者
class
ConsumerThread
extends
Thread {
private
Warehouse
warehouse
;
public
ConsumerThread(Warehouse
warehouse
) {
this
.
warehouse
=
warehouse
;
}
@Override
public
void
run() {
while
(
true
) {
this
.
warehouse
.reduce();
try
{
Thread.
sleep
(500);
}
catch
(InterruptedException
e1
) {
e1
.printStackTrace();
}
}
}
}
public
class
DemoTest {
public
static
void
main(String[]
args
) {
Warehouse
warehouse
=
new
Warehouse();
ProducerThread
pt
=
new
ProducerThread(
warehouse
);
ConsumerThread
ct
=
new
ConsumerThread(
warehouse
);
ProducerThread
pt1
=
new
ProducerThread(
warehouse
);
ConsumerThread
ct1
=
new
ConsumerThread(
warehouse
);
ProducerThread
pt2
=
new
ProducerThread(
warehouse
);
ConsumerThread
ct2
=
new
ConsumerThread(
warehouse
);
pt
.start();
pt1
.start();
pt2
.start();
ct
.start();
ct1
.start();
ct2
.start();
}
}