Java同時プログラミング---スレッド間の通信問題
4220 ワード
一.スレッド間の通信
1.コンセプト
スレッドはオペレーティングシステムにおける独立した個体であるが、これらは特殊な処理を経ることなく全体とすることができず、スレッド間の通信は全体の必須の方式の一つとなる.スレッドに通信指揮が存在すると、システム間のインタラクティビティがより強くなり、CPUの利用率を高めると同時に、開発者にスレッドタスクの処理過程において有効な制御と監督を行う.
2.コードの例
2.1オリジナル方式によるスレッド通信の実現
2.2 wait/notifyメソッドによるスレッド間の通信
3.コード分析
wait/notify法を用いるスレッド間の通信を実現する.(注意この2つの方法はいずれもObjectクラスの方法である.換言すればJavaはすべてのオブジェクトにこの2つの方法を提供している)
3.1 waitとnotifyはsynchronizedキーワードと組み合わせて使用する必要があります
3.2 waitメソッドロック解除、notifyメソッドロック解除しない
1.コンセプト
スレッドはオペレーティングシステムにおける独立した個体であるが、これらは特殊な処理を経ることなく全体とすることができず、スレッド間の通信は全体の必須の方式の一つとなる.スレッドに通信指揮が存在すると、システム間のインタラクティビティがより強くなり、CPUの利用率を高めると同時に、開発者にスレッドタスクの処理過程において有効な制御と監督を行う.
2.コードの例
2.1オリジナル方式によるスレッド通信の実現
package com.thread.message;
import java.util.ArrayList;
import java.util.List;
public class ListAdd1 {
/**volatile , notify wait */
private volatile static List list = new ArrayList();
public void add() {
list.add("bjsxt");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
final ListAdd1 list1 = new ListAdd1();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
for (int i = 0; i < 10; i++) {
list1.add();
System.out.println(" : " + Thread.currentThread().getName() + " ..");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(list1.size() == 5){
System.out.println(" : " + Thread.currentThread().getName() + "list size = 5 ...");
throw new RuntimeException();
}
}
}
},"t2");
t1.start();
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.start();
}
}
2.2 wait/notifyメソッドによるスレッド間の通信
package com.thread.message;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import org.omg.Messaging.SyncScopeHelper;
/**
* wait notify , wait ,notify
*
* @author Administrator
*
*/
public class ListAdd2 {
private volatile static List list = new ArrayList();
public void add() {
list.add("bjsxt");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
final ListAdd2 list2 = new ListAdd2();
// 1. lock
// wait notify , synchronized
final Object lock = new Object(); //
final CountDownLatch countDownLatch = new CountDownLatch(1);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
synchronized (lock) {
for (int i = 0; i < 10; i++) {
list2.add();
System.out.println(" : " + Thread.currentThread().getName() + " ..");
Thread.sleep(500);
if (list2.size() == 5) {
System.out.println(" !");
// countDownLatch.countDown(); // , ,
lock.notify();
}
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (lock) { //
if (list2.size() == 5) {
try {
System.out.println("t2 ... ");
// countDownLatch.await();
lock.wait(); // notif
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(" : " + Thread.currentThread().getName() + " ...");
throw new RuntimeException();
}
}
}, "t2");
t2.start();
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t1.start();
}
}
3.コード分析
wait/notify法を用いるスレッド間の通信を実現する.(注意この2つの方法はいずれもObjectクラスの方法である.換言すればJavaはすべてのオブジェクトにこの2つの方法を提供している)
3.1 waitとnotifyはsynchronizedキーワードと組み合わせて使用する必要があります
3.2 waitメソッドロック解除、notifyメソッドロック解除しない