synchronized(this)柳暗花明又一村
4763 ワード
今日テストクラスを書いて、主にwait(long timeout)が自動的にnotifyになるかどうかをテストして、それから発見します
奇妙なものがある.
呼び出しtestWait 1000_2方法で得られた結果は私が望んでいない(スレッド0は常に実行され、スレッド1は実行されない)が、世界の結果は正反対で、良いこと2つのスレッドは関係なく、テスト結果は以下の通りである.
しかし、testWait 1000を実行するのはちょうど私が望んだ結果で、最初は理解できませんでした.その後、thisを印刷してmysteryを発見しました.
2つのthisの住所が全く違うことに気づいて、よく考えてみると豁然としています.
奇妙なものがある.
package com.hp.thread.chapter04;
public class WaitAndNotify {
private Object obj = new Object();
public static void testPureWait(){
new Thread(new Runnable(){
public void run() {
synchronized (this) {
try {
System.out.println("thread 0");
wait();
System.out.println("thread 0 waited...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable(){
public void run() {
synchronized (this) {
try {
System.out.println("thread 1");
wait(1000);
System.out.println("thread 1 waited...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
public void testWait1000(){
new Thread(new Runnable(){
public void run() {
System.out.println("thread 0 " + this);
synchronized (obj) {
while(true){
try {
System.out.println("thread 0 running...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
new Thread(new Runnable(){
public void run() {
System.out.println("thread 1 " + this);
synchronized (obj) {
try {
while(true){
wait(1000);
System.out.println("thread 1 waited...");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
// this, 2 , ?
// this , new Thread(new Runnable(){}).start()
// , , this new Thread() WaitAndNotify
public void testWait1000_2(){
new Thread(new Runnable(){
public void run() {
synchronized (this) {
while(true){
try {
System.out.println("thread 0");
System.out.println("thread 0 running...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
new Thread(new Runnable(){
public void run() {
synchronized (this) {
try {
while(true){
System.out.println("thread 1");
wait(1000);
System.out.println("thread 1 waited...");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
public static void testWait(){
new Thread(new Runnable(){
public void run() {
while(true){
synchronized (this) {
try {
System.out.println("...");
wait();
System.out.println("waited...");
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
new Thread(new Runnable(){
public void run() {
while(true){
synchronized (this) {
try {
notifyAll();
System.out.println("notify...");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
}
/**
* @param args
*/
public static void main(String[] args) {
// testPureWait();
// testWait();
new WaitAndNotify().testWait1000();
}
}
呼び出しtestWait 1000_2方法で得られた結果は私が望んでいない(スレッド0は常に実行され、スレッド1は実行されない)が、世界の結果は正反対で、良いこと2つのスレッドは関係なく、テスト結果は以下の通りである.
thread 0
thread 0 running...
thread 1
thread 1 waited...
thread 0
thread 0 running...
thread 1
thread 0
thread 0 running...
thread 1 waited...
thread 1
しかし、testWait 1000を実行するのはちょうど私が望んだ結果で、最初は理解できませんでした.その後、thisを印刷してmysteryを発見しました.
thread 0 com.hp.thread.chapter04.WaitAndNotify$3@525483cd
thread 0 running...
thread 1 com.hp.thread.chapter04.WaitAndNotify$4@67f1fba0
thread 0 running...
thread 0 running...
thread 0 running...
thread 0 running...
2つのthisの住所が全く違うことに気づいて、よく考えてみると豁然としています.