Javaマルチスレッド通信に関するまとめ


スレッド間の通信は、生産者、消費者モデルが一般的です.
package com.cgroup.thread;

public class PC {

	public static void main(String[] args) {
		Q q = new Q();
		Consumer c = new Consumer(q);
		Producer p = new Producer(q);
	}

}

class Q {

	int n;
	boolean isValid;

	public synchronized int getN() {
		while (!isValid) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("get n:" + n);
		isValid = false;
		this.notify();
		return n;
	}

	public synchronized void setN(int n) {
		while (isValid) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		this.n = n;
		System.out.println("set n:" + n);
		isValid = true;
		this.notify();
	}

}

class Consumer extends Thread {
	Q q;

	public Consumer(Q q) {
		this.q = q;
		start();
	}

	public void run() {
		int i = 0;
		for (int j = 0; j < 10; j++) {
			q.setN(i++);
		}
	}
}

class Producer extends Thread {

	Q q;

	public Producer(Q q) {
		this.q = q;
		start();
	}

	public void run() {
		for (int i = 0; i < 10; i++) {
			q.getN();
		}
	}
}

もう1つは,ストリームを介してスレッド間の通信を実現することである.
 
package com.cgroup.thread;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class Pipe {

	public static void main(String[] args) throws Exception {

		PipedInputStream in = new PipedInputStream();
		PipedOutputStream out = new PipedOutputStream(in);
		Sender s = new Sender(out);
		Receiver r = new Receiver(in);
		Thread thread1 = new Thread(s);
		Thread thread2 = new Thread(r);
		thread1.start();
		thread2.start();
	}

}

class Sender implements Runnable {

	OutputStream out;

	public Sender(OutputStream out) {
		this.out = out;
	}

	public void run() {
		int value;

		try {
			for (int i = 0; i < 5; i++) {
				double tmp=Math.random() ;
				value = (int) (tmp*256);
				out.write(value);
				System.out.println("send:" + value);
				Thread.sleep((long) (Math.random() * 1000));
			}
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}
}

class Receiver implements Runnable {

	InputStream in;

	public Receiver(InputStream in) {
		this.in = in;
	}

	public void run() {
		int value;

		try {
			while ((value = in.read()) != -1) {
				System.out.println("received:" + value);
			}
			System.out.println("pipe closed");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}
 
 
 
1.必ずしもそうではありません.データを書くには保護が必要で、データを読むには保護が必要ありません.読む、書く、守る必要がある
2.スレッドのブロックを引き起こす原因は、sleepメソッドを呼び出し、waitメソッドを呼び出し、io操作を呼び出し、スレッドがロックされたメソッドまたは同期ブロックを実行することである.