最通俗易解的方式:
实例1:
class ThreadA {
static Object o1 = new Object();//可以是任意一个对象,或者自定义的对象
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
System.out.println("b is start....");
synchronized (o1)// 主线程获取o1的对象锁
{
try {
System.out
.println("Waiting for b to complete...");
o1.wait();//o1的对象锁释放,主线程进入等待状态
System.out
.println("Completed.Now back to main thread");
} catch (InterruptedException e) {
}
}
System.out.println("Total is :" + b.total);
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized (o1) {//ThreadB获取o1的对象锁
System.out.println("ThreadB is running..");
for (int i = 0; i < 5; i++) {
total += i;
System.out.println("total is " + total);
}
o1.notify();//ThreadB释放o1的对象锁,通知其他等待o1对象锁的线程继续运行
}
}
}
o1.wait()没设置时间,需要o1.notify(),主线程才能继续运行
输出有以下两种情况:
b is start....
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Waiting for b to complete...
b is start....
Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Completed.Now back to main thread
Total is :10
实例2:
//o1.notify();这句话注释掉
输出的一种情况:
b is start....
Waiting for b to complete...
Sat Sep 29 10:07:56 CST 2018
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
o1.wait()没设置时间,没有o1.notify(),主线程不能继续运行
实例3:o1.wait(xxx)设置时间,没有o1.notify()
class ThreadA {
static Object o1 = new Object();
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
System.out.println("b is start....");
synchronized (o1)// 主线程获取o1的对象锁
{
try {
System.out
.println(new Date() + "Waiting for b to complete...");
o1.wait(3000);//o1的对象锁释放2s,主线程进入等待状态,需要通知才能获取锁
System.out
.println(new Date() + "Completed.Now back to main thread");
} catch (InterruptedException e) {
}
}
System.out.println("Total is :" + b.total);
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized (o1) {//ThreadB获取o1的对象锁
System.out.println("ThreadB is running..");
for (int i = 0; i < 5; i++) {
total += i;
System.out.println("total is " + total);
}
try {
// Thread.sleep(5000);//ThreadB执行完后,主线程继续执行
Thread.sleep(2000);//ThreadB先执行完,然后主线程再等待1s,主线程继续执行
// Thread.sleep(3000);//ThreadB先执行完,紧接着主线程继续执行
} catch (InterruptedException e) {
e.printStackTrace();
}
//o1.notify();//ThreadB释放o1的对象锁,通知其他等待o1对象锁的线程继续运行
}
}
}
输出:
Thread.sleep(5000);
b is start....
Sun Sep 30 14:11:05 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:11:10 CST 2018Completed.Now back to main thread
Total is :10
Thread.sleep(2000);
b is start....
Sun Sep 30 14:11:41 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:11:44 CST 2018Completed.Now back to main thread
Total is :10
Thread.sleep(3000);
b is start....
Sun Sep 30 14:09:51 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:09:54 CST 2018Completed.Now back to main thread
Total is :10
实例4:o1.wait(xxx)设置时间,有o1.notify()
class ThreadA {
static Object o1 = new Object();
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
System.out.println("b is start....");
synchronized (o1)// 主线程获取o1的对象锁
{
try {
System.out
.println(new Date() + "Waiting for b to complete...");
o1.wait(3000);//o1的对象锁释放2s,主线程进入等待状态,需要通知才能获取锁
System.out
.println(new Date() + "Completed.Now back to main thread");
} catch (InterruptedException e) {
}
}
System.out.println("Total is :" + b.total);
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized (o1) {//ThreadB获取o1的对象锁
System.out.println("ThreadB is running..");
for (int i = 0; i < 5; i++) {
total += i;
System.out.println("total is " + total);
}
try {
// Thread.sleep(5000);//ThreadB执行完后,主线程继续执行,有无o1.notify();均是
// Thread.sleep(2000);//ThreadB先执行完,主线程不用再等待1s,主线程继续执行
Thread.sleep(3000);//ThreadB先执行完,紧接着主线程继续执行,有无o1.notify();均是
} catch (InterruptedException e) {
e.printStackTrace();
}
o1.notify();//ThreadB释放o1的对象锁,通知其他等待o1对象锁的线程继续运行
}
}
}
输出:
Thread.sleep(5000);
b is start....
Sun Sep 30 14:11:05 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:11:10 CST 2018Completed.Now back to main thread
Total is :10
Thread.sleep(2000);
b is start....
Sun Sep 30 14:14:59 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:15:01 CST 2018Completed.Now back to main thread
Total is :10
Thread.sleep(3000);
b is start....
Sun Sep 30 14:09:51 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:09:54 CST 2018Completed.Now back to main thread
Total is :10
实例3,4中,sleep不释放锁,所以主线程要等待,如果换成o1.wait,会释放锁,有无o1.notify时,可以自行实验。
要分析这个程序,首先要理解 notify() 和 wait(),这两个方法本来就不属于 Thread 类,而是属于最底层的 object 基础类的,也就是说不光是 Thread,每个对象都有 notify 和wait 的功能,为什么?因为他们是用来操纵锁的,而每个对象都有锁,锁是每个对象的基础,既然锁是基础的,那么操纵锁的方法当然也是最基础了。
参考:https://blog.csdn.net/defonds/article/details/4923775?utm_source=copy