java中的wait和sleep都可用于暂停当前线程的执行,执行另外一个线程。
来看一个使用wait()来实现打印ABAB....的程序:
package com.lql.thread2;
public class Print1 implements Runnable {
public int count = 10;
@Override
public void run() {
// TODO Auto-generated method stub
while (count > 0) {
synchronized (Test.obj) {
System.out.print("A");
count--;
Test.obj.notify();
try {
// Thread.sleep(100);
Test.obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
package com.lql.thread2;
public class Print2 implements Runnable {
public int count = 10;
@Override
public void run() {
// TODO Auto-generated method stub
while (count > 0) {
synchronized (Test.obj) {
System.out.print("B");
count--;
Test.obj.notify();//唤醒因为调用对象wait()而等待的线程
try {
Test.obj.wait();//是否占有的对象锁
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
package com.lql.thread2;
public class Test {
public static Object obj = new Object();
public static void main(String[] args) {
Print1 print1 = new Print1();
Print2 print2 = new Print2();
Thread thread = new Thread(print1);
Thread thread2 = new Thread(print2);
thread.setPriority(2);
thread.setPriority(1);
thread.start();
thread2.start();
}
}
ABABABABABABABABABAB
以上是使用wait()来实现两个线程轮流打印A,B,最终输出ABAB....
如果用sleep就不能打印ABAB...的效果
sleep和wait的区别:
1.sleep()是线程类的方法,wait()是Object的方法。
2.sleep()方法使该线程休眠时,该线程不会释放对象锁,而wait()使当前线程等待时,当前线程会释放锁占用的对象锁。(这个区别我觉得是sleep和wait最为重要的区别,因为线程wait时,会释放对象锁,所以才会有第三个区别的存在)
3.wait()方法必须在同步代码块中使用,wait方法通常需要与notify()或notifyAll()方法配合使用。
因为wait方法会使当前线程释放对象锁,所以wait()方法必须在同步块中使用。同步块指定了当前线程获取那个对象的对象锁,当该对象调用自己的wait()方法时,可以将该对象的对象锁进行释放,该对象调用notify去唤醒在等待该对象锁的线程。从这个特点中也可以理解wait()方法可以用于线程间通信的含义。obj.wait()方法释放obj对象的对象锁,同时obj.notify()负责唤醒等待对象锁的线程,使该线程有机会得到处理机资源去执行同步代码块的方法。