一般的な同時プログラミングツール
5955 ワード
1.CountDownLatch
このツールは主に1つのタスクを分解し、すべてのサブタスクが完了するのを待ってから次の操作を行います.この待機操作は主にawait制御です.カウント値はリセットできません.リセットが必要な場合はCyclicBarrierを使用します.
次の例では、doneが印刷されるまで、すべてのスレッドが完了していることがわかります.
コメントが削除されたらawait(); doneが中間で印刷されていることに気づき、サブタスクが完了するのを待たずに実行されました.
package concurrent;
import java.util.concurrent.CountDownLatch;
public class TestCountDownLatch {
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(10);
for(int i= 0; i<10;i++){
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName() +"--> begin");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"--> end");
latch.countDown();
}
},String.valueOf(i)).start();
}
latch.await();
System.out.println("done------------");
}
}
2.CyclicBarrier
このツールは、主に各タスクに複数のフェーズがあります.例えば、3番目のフェーズが開始される前提は、2番目のフェーズのすべての人がタスクを完了しなければなりません.
CyclicBarrierにrunnableオブジェクトを注入すると、カウンタが0に達すると自動的にイベントがトリガーされ、カウント値がリセットされます.
package concurrent;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class TestCyclicBarrier {
private final static CyclicBarrier cyclicBarrier = new CyclicBarrier(10,new Runnable() {
public void run() {
System.out.println(" ");
}
});
public static void main(String[] args) throws InterruptedException {
for(int i= 0; i<10;i++){
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName() +"--> begin run");
try {
cyclicBarrier.await();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (BrokenBarrierException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"--> begin jump");
try {
cyclicBarrier.await();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (BrokenBarrierException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"--> begin walk");
try {
cyclicBarrier.await();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (BrokenBarrierException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"--> end");
}
},String.valueOf(i)).start();
}
}
}
実行結果
0--> begin run
3--> begin run
2--> begin run
1--> begin run
5--> begin run
4--> begin run
7--> begin run
6--> begin run
9--> begin run
8--> begin run
8--> begin jump
3--> begin jump
1--> begin jump
4--> begin jump
0--> begin jump
9--> begin jump
6--> begin jump
7--> begin jump
5--> begin jump
2--> begin jump
2--> begin walk
1--> begin walk
9--> begin walk
6--> begin walk
4--> begin walk
3--> begin walk
8--> begin walk
5--> begin walk
7--> begin walk
0--> begin walk
7--> end
5--> end
3--> end
9--> end
6--> end
8--> end
4--> end
2--> end
1--> end
0--> end
3.Semaphor
カウンタの価値は、nサブタスクのみがリソースにアクセスできるように制御することです.次の例のように、3つのプロセスしか同時に存在しません.
package concurrent;
import java.util.concurrent.Semaphore;
public class TestSemaphor {
static Semaphore semaphore = new Semaphore(3, true);
public static void main(String[] args) {
for(int i= 0; i<10;i++){
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
semaphore.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"--> begin ");
try {
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.out.println(Thread.currentThread().getName()+"--> end");
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}