JAvaスレッド通信

2692 ワード

スレッド通信といえば、生産者と消費者、哲学者の食事問題を思い浮かべます.次の例は、生産者と消費者がスレッド間の通信を実現することです.

package com.lamp.test;

public class Cake {
	private int number = 0;
	
	public synchronized void increase(){
		while(0 != number){		//                   ,      if   ,     2        while               
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		number++;				//          0  1, 0  1        ,       
		System.out.println(number);
		this.notify();
	}
	
	public synchronized void decrease(){
		while(0 == number){
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		number--;
		System.out.println(number);
		this.notify();
	}
}

生産者プロセスクラス

package com.lamp.test;

public class Producer extends Thread {

	private Cake cake;

	public Producer(Cake cake) {
		this.cake = cake;
	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				Thread.sleep((long) (Math.random() * 1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			this.cake.increase();
		}

	}
}


消費者プロセスクラス

package com.lamp.test;

public class Consumer extends Thread{
	private Cake cake = null;

	public Consumer(Cake cake) {
		this.cake = cake;
	}
	
	@Override
	public void run(){
		for(int i=0; i<10; i++){
			try {
				Thread.sleep((long) (Math.random() * 1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			this.cake.decrease();
		}
		
	}

}

テストクラスを書く

package com.lamp.test;

public class CakeTest {

	public static void main(String[] args) {
		Cake cake = new Cake();
		
		Thread t1 = new Producer(cake);
		Thread t2 = new Consumer(cake);		//          
		
		Thread t3 = new Producer(cake);
		Thread t4 = new Consumer(cake);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}

}

waitメソッドとnotifyメソッドは、Objectメソッドで定義されており、finalであるため、すべてのjavaクラスに継承されますが書き換えることはできません.この2つのメソッドの呼び出しはsynchronizedメソッドまたはsynchronizedブロックでなければなりません.現在のスレッドはオブジェクトロックを取得しており、スレッドがwaitメソッドを実行するとオブジェクトロックが解放されます.