结论:
wait(time), notify(), notifyall?
一个线程拿到一个对象上的锁,才能调用这个对象的wait(time),notify,notifyall!!!否则会抛异常。
线程没有休眠和苏醒的概念,只有从调度队列排除和加入的概念。前者两个概念要误导人!!
调用wait(time)会做3件事:
1、使当前线程加入当这个对象的等待线程集合,这个是为什么线程要拿到这个对象的锁才能够调用wait。(加入等待set)
2、同时会使这个线程释放他拿到这个对象上的锁。(还锁)
3、从调度队列中排除。
调用wait的线程重新加入调用队列,只有当一下四件事情发生时:
1、有其他线程调用这个对象的notifyall,
2、有其他线程调用notify,且这个线程又刚好随机被notify选中
3、有其他线程调用这个对象intercept方法,将线程的中断标志位置位(当线程投入使用时, wait方法要抛一个中断异常)
4、时间超时了。
代码验证:
控制台输出:
sub thread1
sub thread2
sub thread3
main thread
代码如下:
public class ThreadTest { private Object o = new Object(); public ThreadTest() { } public void test() throws Exception{ Runnable runnable = new Runnable() { @Override public void run() { try { System.out.println("sub thread1"); }catch (Exception e){ } } }; final Thread thread = new Thread(runnable); thread.start(); Runnable runnable1 = new Runnable() { @Override public void run() { try { thread.join(); System.out.println("sub thread2"); }catch (Exception e){ } } }; final Thread main = Thread.currentThread(); Thread thread1 = new Thread(runnable1); thread1.start(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i <= 1000000000; i++){ if (i == 1000000000){ System.out.println("sub thread3"); } } try { main.interrupt();//这里写main.interupt();想过一样 }catch (Exception e){ } } }).start(); thread1.join(); try{ synchronized (o){ System.out.println("main wait"); o.wait(); } }catch (Exception e){ System.out.println("main thread excet"); } } public static void main(String[] args) throws Exception{ new ThreadTest().test(); } }