java中wait和notify的简单理解
1 它们都是Object的属性;
2 wait:释放对象锁;由于把锁释放了,当前线程就会卡住,继续再等待获取锁的机会(也许是干了一半的活后,就把活交出去了,然后等待继续干活的机会);
3 notify:告诉其中一个等待的线程(具体哪一个不知道),我已经用完这个对象,你可以继续用了
4 它们都要包含在synchronized块里,只有先锁住这个对象,才能进行wait、notify操作;
例子:
1 定义一个普通对象
public class MyObj {
public String name;
}
2 主线程类,定义MyObj对象,new两个线程
public class TestMain {
public static MyObj obj = new MyObj();
/**
* @param args
*/
public static void main(String[] args) throws Throwable {
new TestMain().myTest();
}
public void myTest() throws Throwable{
Test1 test1 = new Test1();
Test2 test2 = new Test2();
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test2);
t1.start();
Thread.sleep(1000);//启动线程1,然后主线程睡眠1秒钟,再启动2
t2.start();
}
}
3 定义线程1,:
public class Test1 implements Runnable{
@Override
public void run() {
synchronized (TestMain.obj) {//占有对象锁
try {
TestMain.obj.name="1";
System.out.println(TestMain.obj.name); //打印出1
TestMain.obj.wait(); //释放对TestMain.obj对象的锁,同时当前线程立即卡住,陷入等待
System.out.println(TestMain.obj.name);//只有线程再次抢到TestMain.obj的锁后,才会运行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4 线程2:
public class Test2 implements Runnable{
@Override
public void run() {
synchronized (TestMain.obj) { //当线程1释放这个对象的锁时,本线程立即得到
TestMain.obj.name = "2"; //改值
TestMain.obj.notify();//通知占用了TestMain.obj且当前是等待的线程(线程1)可以继续,但是必须等到本synchronized块执行完毕。
TestMain.obj.name = "3";
TestMain.obj.name = "4";
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
TestMain.obj.name = "7";//执行完毕,此时线程1被唤醒,会打印出7
}
}
}
结果显示1和7