(帮朋友看时候学了一下这方面知识 ,有错误请纠正)
两种方式
- wait() 、notify() 和notifyAll()
- Condition:在Condition对象中,与wait,notify和notifyAll方法对应的分别是await,signal,signalAll。但是,Condition对Object进行了扩展,因而它也包含wait和notify方法。
注意事项讲解
- Thread.currentThread().getName()作用,获取线程的名字,我没有看源代码只是通过自己测试得到的理解,我们通过这个方法可以得到线程的名字格式Thread-0、Thread-1、Thread-2…………….这后面的数字id标识怎么来的呢,是根据我们自定义线程类的初始化顺序来定的。
- object.notifyAll()唤醒所有阻塞的线程,并且测试中的执行顺序没有按照thread.start的顺序输出,而是按照实例化thread的顺序输出的阻塞的线程。
- object.notify() 唤醒某一个阻塞线程,测试中是唤醒的是第一个调用start()方法的线程
- 通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。然后通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程终止。
- 搜资料所得:notifyall,虽然是对每个wait的对象都调用一次notify,但是这个还是有顺序的,每个对象都保存这一个等待对象链,调用的顺序就是这个链的顺序。其实启动等待对象链中各个线程的也是一个线程,在具体应用的时候,需要注意一下。
代码实例
package cn.neuq;
public class Test {
public static Object object = new Object();
public static void main(String[] args) {
//Thread.currentThread().getName()名字中的顺序是按照实例化顺序定义的
Thread1 thread1 = new Thread1();//实例化Thread1--wait()
Thread2 thread2 = new Thread2();//实例化Thread2--调用notify()或者notifyAll()
Thread3 thread3 = new Thread3();//实例化Thread3--wait()
Thread4 thread4 = new Thread4();//实例化Thread4--wait()
/**
*
* 通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。
* 然后通过此Thread类调用方法run()来完成其运行操作的,
* 这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程终止,
* 由于Thread1类中run方法中调用了wait()方法然后线程阻塞,因此并没有继续执行下面的两条Thread1输出的代码
*
* */
/**
* thread3.start();
* thread4.start();
* thread1.start();
* 对于notify()而言此时运行是先唤醒的thread3
* */
//此时如果thread2中是notify,那么根据先启动顺序唤醒一个线程,thread3在thread1前面那么先唤醒thread4
thread4.start();
thread3.start();
thread1.start();
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
*
* thread2线程启动,由于Thread2类中run()方法调用了notify
* 调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程
* 如果有多个线程都在等待这个对象的monitor,则只能唤醒其中一个线程
* 此时thread2继续执行完成run()方法释放锁
* 然后执行唤醒的thread1,接着wait()代码之后继续执行
*
* */
thread2.start();
}
static class Thread1 extends Thread{
@Override
public void run() {
synchronized (object) {
try {
object.wait();//调用wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(即锁)
System.out.println("Thread1线程"+Thread.currentThread().getName()+"调用了object.wait()");
} catch (InterruptedException e) {
}
System.out.println("Thread1线程"+Thread.currentThread().getName()+"获取到了锁");
}
}
}
static class Thread2 extends Thread{
@Override
public void run() {
synchronized (object) {
//object.notify();
object.notifyAll();//唤醒所有的wait的
System.out.println("Thread2线程"+Thread.currentThread().getName()+"调用了object.notify()");
}
System.out.println("Thread2线程"+Thread.currentThread().getName()+"释放了锁");
}
}
static class Thread3 extends Thread{
@Override
public void run() {
synchronized (object) {
try {
object.wait();//调用wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(即锁)
System.out.println("Thread3线程"+Thread.currentThread().getName()+"调用了object.wait()");
} catch (InterruptedException e) {
}
System.out.println("Thread3线程"+Thread.currentThread().getName()+"获取到了锁");
}
}
}
static class Thread4 extends Thread{
@Override
public void run() {
synchronized (object) {
try {
object.wait();//调用wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(即锁)
System.out.println("Thread4线程"+Thread.currentThread().getName()+"调用了object.wait()");
} catch (InterruptedException e) {
}
System.out.println("Thread4线程"+Thread.currentThread().getName()+"获取到了锁");
}
}
}
}