JAvaスレッド-スレッドの通信
スレッド通信の3つの方式
同期
whileポーリング方式
wait()/notify()方式
スレッド通信の3つの方式
同期
ここでいう同期はsynchronizedキーワードでスレッド間の通信を実現し,コードで例示する.
上記のコードを解析すると,スレッド1とスレッド2はobjというオブジェクトを操作し,スレッド1がadd()メソッドを実行するとobjというオブジェクトをロックとして取得し,このときスレッド2はdel()メソッドを行うことができない.スレッド1がadd()メソッドを実行した後にスレッド2が実行されると、スレッド間の通信が実現される.
この方法は本質的に共有変数式通信であり,誰がロックを手に入れたかは実行できる.
whileポーリング方式
この方式は2つのスレッドで1つのスレッドが絶えず条件を変更し、もう1つのスレッドにはwhileサイクルがあり、条件が成立するまで条件を判断し続け、他のコードブロックの実行を開始するが、実際には複数のスレッドが同時に実行され、この方式ではCPU性能の一部を犠牲にする.
上記のコードでは、スレッド2の条件が満たされない場合、無意味なループが行われている.
wait()/notify()方式
この方式には古典的な例がある.生産者-消費者モデルであり、倉庫の貨物が不足している場合、消費者は待たなければならない.生産者が十分な貨物を生産するのは消費者にメッセージを送ることであり、消費者は運行を続けることができる.同様に、倉庫がいっぱいになると生産者はしばらく停止する必要があり、一部の貨物が消費されると消費者は生産者にメッセージを送り、生産者が仕事を続けることができることを示した.
実行結果:
容量不足-現在容量:1000生産1000-現在容量:2000消費2000-倉庫容量:0生産1000-現在容量:1000容量不足-現在容量:1000生産1000-現在容量:2000生産1000-現在容量:2000生産1000-現在容量:3000消費2000-倉庫容量:1000生産1000-当前容量:2000消費2000-倉庫容量:0生産1000-現在容量:1000容量不足-現在容量:1000生産1000-現在容量:2000消費2000-倉庫容量:0
同期
whileポーリング方式
wait()/notify()方式
スレッド通信の3つの方式
同期
ここでいう同期はsynchronizedキーワードでスレッド間の通信を実現し,コードで例示する.
class Obj{
int count = 0;
public synchronized void add(){
//do something
count++;
}
public synchronized void del(){
//do something
count--;
}
}
public class Demo4 {
static Obj obj = new Obj();
public static void main(String[] args) {
// 1
new Thread(new Runnable(){
public void run() {
for(int i = 0;i < 10;i++){
obj.add();
}
}
}).start();
// 2
new Thread(new Runnable(){
public void run() {
for(int i = 0;i < 5;i++){
obj.del();
}
}
}).start();
//
while(Thread.activeCount() > 1){
Thread.yield();
}
System.out.println("main:"+obj.count);
}
}
上記のコードを解析すると,スレッド1とスレッド2はobjというオブジェクトを操作し,スレッド1がadd()メソッドを実行するとobjというオブジェクトをロックとして取得し,このときスレッド2はdel()メソッドを行うことができない.スレッド1がadd()メソッドを実行した後にスレッド2が実行されると、スレッド間の通信が実現される.
この方法は本質的に共有変数式通信であり,誰がロックを手に入れたかは実行できる.
whileポーリング方式
この方式は2つのスレッドで1つのスレッドが絶えず条件を変更し、もう1つのスレッドにはwhileサイクルがあり、条件が成立するまで条件を判断し続け、他のコードブロックの実行を開始するが、実際には複数のスレッドが同時に実行され、この方式ではCPU性能の一部を犠牲にする.
class Obj{
int count = 0;
public synchronized void add(){
//do something
count++;
}
public synchronized void del(){
//do something
count--;
}
}
public class Demo4 {
static Obj obj = new Obj();
public static void main(String[] args) {
// 1
new Thread(new Runnable(){
@Override
public void run() {
for(int i = 0;i < 10;i++){
obj.add();
System.out.println("++");
}
}
}).start();
// 2
new Thread(new Runnable(){
@Override
public void run() {
boolean b = true;
while(b){
if(obj.count == 5){
System.out.println(" 2 ");
b = false;
}
}
}
}).start();;
}
上記のコードでは、スレッド2の条件が満たされない場合、無意味なループが行われている.
wait()/notify()方式
この方式には古典的な例がある.生産者-消費者モデルであり、倉庫の貨物が不足している場合、消費者は待たなければならない.生産者が十分な貨物を生産するのは消費者にメッセージを送ることであり、消費者は運行を続けることができる.同様に、倉庫がいっぱいになると生産者はしばらく停止する必要があり、一部の貨物が消費されると消費者は生産者にメッセージを送り、生産者が仕事を続けることができることを示した.
class Model {
private int count;
public Model(){
this.count = 1000;
}
public synchronized void produce(int val){
if(count > 5000){
try {
System.out.println(" ");
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
count += val;
System.out.println(" 1000- :"+get());
this.notify();
}
}
public synchronized void consume(int val){
if(count < val){
System.out.println(" - :"+get());
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
count -= val;
System.out.println(" 2000- :"+get());
this.notifyAll();
}
}
public int get(){
return this.count;
}
}
public class Demo8 {
public static void main(String[] args) {
final Model model = new Model();
/**
*
*/
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
model.produce(1000);
}
}
}).start();
/**
*
*/
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
model.consume(2000);
}
}
}).start();
}
}
実行結果:
容量不足-現在容量:1000生産1000-現在容量:2000消費2000-倉庫容量:0生産1000-現在容量:1000容量不足-現在容量:1000生産1000-現在容量:2000生産1000-現在容量:2000生産1000-現在容量:3000消費2000-倉庫容量:1000生産1000-当前容量:2000消費2000-倉庫容量:0生産1000-現在容量:1000容量不足-現在容量:1000生産1000-現在容量:2000消費2000-倉庫容量:0