synchronized(this) 버드나무 어둡고 꽃 밝은 또 다른 마을

4867 단어 synchronized
오늘 테스트 클래스를 하나 썼는데 주로 wait(long timeout)가 도대체 자동으로 notify가 되는지 테스트했는데 나중에 발견했어요.
괴상한 것들.
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();
	}

}

TestWait1000 호출2 방법이 얻은 결과는 내가 기대한 것이 아니다. (라인 0은 시종 운행하고 있고 라인 1은 운행하지 않는다) 그러나 세계의 결과는 정반대이다. 좋은 일은 두 라인이 상관없다. 테스트 결과는 다음과 같다.
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

그러나testWait1000을 실행하는 것은 마침 내가 원하는 결과였다. 처음에는 백 번 생각해도 풀리지 않았는데, 나중에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...

두 this의 주소가 완전히 다르다는 것을 발견하고 곰곰이 생각해 보니 명랑해졌다.

좋은 웹페이지 즐겨찾기