CountDownLatch
概念
一种线程的辅助,允许一个操作等待直到某个或某组操作完成再执行
倒数,计数为0时执行
代码
demo1
package top.ygy.thread;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* @Description: TODO(CountDownLatch测试)
* @author yangguangyuan
* @date 2019年5月31日
*
* 第一种用法:主线程执行完后,再执行其他线程
* 主线程等待其他线程执行完,再执行主线程
* 第二种用法:将一个任务分成多个任务,执行完成之后,在执行其他任务
*/
public class CountDownLatchDemo {
public static void main(String[] args) {
Driver driver = new Driver();
try {
driver.main();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Driver {
void main() throws InterruptedException {
int N = 3;
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
// doSomethingElse(); // don't let run yet
System.out.println(1+"主线程执行任务,其他线程等待中");
TimeUnit.MILLISECONDS.sleep(3000);
System.out.println(1+"主线程执行完成,开始执行其他线程");
//主线程准备完成,开始执行其他线程
startSignal.countDown(); // let all threads proceed
// doSomethingElse();
System.out.println(2);
doneSignal.await(); // wait for all to finish
System.out.println("4");
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {
}
}
void doWork() {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "");
System.out.println(Thread.currentThread().getName() + "_3");
}
}
demo2
package top.ygy.thread;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* @Description: TODO(CountDownLatch测试)
* @author yangguangyuan
* @date 2019年5月31日
*
* 第一种用法:主线程执行完后,再执行其他线程
* 第二种用法:主线程等待其他线程执行完,再执行主线程
*/
public class CountDownLatchDemo2 {
public static void main(String[] args) {
Driver2 driver = new Driver2();
try {
driver.main();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Driver2 { // ...
void main() throws InterruptedException {
int N = 3;
CountDownLatch doneSignal = new CountDownLatch(N);
Executor e = Executors.newFixedThreadPool(20);
for (int i = 0; i < N; ++i) // create and start threads
e.execute(new WorkerRunnable(doneSignal, i));
doneSignal.await(); // wait for all to finish
}
}
class WorkerRunnable implements Runnable {
private final CountDownLatch doneSignal;
private final int i;
WorkerRunnable(CountDownLatch doneSignal, int i) {
this.doneSignal = doneSignal;
this.i = i;
}
public void run() {
try {
doWork(i);
doneSignal.countDown();
} catch (Exception ex) {
} // return;
}
void doWork(int i) {
System.out.println("测试"+i);
}
}
CyclicBarrier
概念
一种线程的辅助,允许一个操作等待直到某个或某组操作完成再执行
正数,计数达到预期值时执行
代码
矩阵计算
package top.ygy.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
/**
* @Description: TODO(CyclicBarrier矩阵示例)
* @author yangguangyuan
* @date 2019年6月6日
*
*/
public class CyclicBarrierDemo {
public static void main(String[] args) {
float[][] matrix = new float[3][3];
int counter = 0;
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[0].length; col++) {
matrix[row][col] = counter++;
}
}
dump(matrix);
new Solver(matrix);
dump(matrix);
}
static void dump(float[][] matrix) {
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[0].length; col++) {
System.out.println(matrix[row][col] + " ");
}
}
}
}
class Solver {
final int N;
final float[][] data;
final CyclicBarrier barrier;
class Worker implements Runnable {
int myRow;
boolean done = false;
Worker(int row) {
myRow = row;
}
boolean done() {
return done;
}
void processRow(int myRow) {
System.out.println("Processing row: " + myRow);
for (int i = 0; i < N; i++) {
data[myRow][i] *= 10;
}
done = true;
}
public void run() {
while (!done()) {
processRow(myRow);
try {
barrier.await();
} catch (Exception ex) {
return;
}
}
}
}
public Solver(float[][] matrix) {
data = matrix;
N = matrix.length;
Runnable barrierAction = new Runnable() {
public void run() {
mergeRows();
}
};
barrier = new CyclicBarrier(N, barrierAction);
List<Thread> threads = new ArrayList<Thread>(N);
for (int i = 0; i < N; i++) {
Thread thread = new Thread(new Worker(i));
threads.add(thread);
thread.start();
}
waitUntilDone();
}
void mergeRows() {
System.out.println("merging");
synchronized ("abc") {
"abc".notify();
}
}
void waitUntilDone() {
synchronized ("abc") {
try {
System.out.println("main thread waiting");
"abc".wait();
System.out.println("mian thread notified");
} catch (Exception e) {
System.out.println("main thread interrupted");
e.printStackTrace();
}
}
}
}
Semaphore
概念
一个计数信号量,信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制
(多个线程争抢多个资源)
代码
抢车位
package top.ygy.thread;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* @Description: TODO(抢车位示例)
* @author yangguangyuan
* @date 2019年6月19日
*
*/
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"\t 抢到车位");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"\t 停车3s后离开车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}