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