信号量模式
实现任务间相互通信,采用信号量或者互斥实现:Semaphore、ReebtrantLock、wait()notify()下例使用 wait() notify() 实现
package ThreadFrame.并行模式;
/**
* @author mojiayi
* @date 2019-02-09 13:54
*/
public class FrameDemo implements Runnable {
private int flag;
private Object object;
FrameDemo(
Object o
){
this.object = o;
}
public static void test(int i){
System.out.println(Thread.currentThread().getName()+" "+i);
}
public void task1(){
synchronized (object) {
test(1);
object.notify();
}
}
public void task2() throws InterruptedException {
synchronized (object) {
object.wait();
test(2);
object.notify();
}
}
public static void main(String[] args) throws InterruptedException {
Object o = new Object();
FrameDemo demo1 = new FrameDemo(o);
FrameDemo demo2 = new FrameDemo(o);
demo1.flag = 1;
new Thread(demo2).start();
Thread.sleep(1000);
new Thread(demo1).start();
}
@Override
public void run() {
if(flag == 1)
task1();
else {
try {
task2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
会和模式
此模式是信号模式的扩展,当第一个任务在等待第二个任务的某一事件,而第二哥任务又在等待第一个任务的某一事件时:public void task1() throws InterruptedException {
synchronized (object) {
test(1);
object.notify();
object.wait();
object.notify();
test(3);
}
}
public void task2() throws InterruptedException {
synchronized (object) {
test(2);
object.notify();
object.wait();
object.notify();
test(4);
}
}
临界模式
此模式用于设置某一临界段来限制执行线程,就是我们所说的同步。多元复用模式
这是临界模式的扩展,在临界模式的基础上限制执行临界段的线程数量,一般用 Semaphore 类实现。package ThreadFrame.并行模式;
import java.util.concurrent.Semaphore;
/**
* @author mojiayi
* @date 2019-02-09 13:54
*/
public class FrameDemo implements Runnable {
private int flag;
private static int i;
Semaphore c;
Semaphore p;
Semaphore m;
public FrameDemo(int flag, Semaphore c,Semaphore p, Semaphore m) {
this.flag = flag;
this.c = c;
this.p = p;
this.m = m;
}
public void consume() throws InterruptedException {
m.acquire();
//System.out.println("2");
if (c.availablePermits() <= 0){
m.release();
return;
}
c.acquire();
i = i - 1;
System.out.println("c: "+p.availablePermits()+" "+c.availablePermits()+" "+m.availablePermits()+" "+i);
if(i<0)
System.exit(0);
p.release();
m.release();
}
public void produce() throws InterruptedException {
m.acquire();
//System.out.println("1");
if(p.availablePermits()<=0) {
m.release();
return;
}
p.acquire();
i = i + 1;
System.out.println("p "+p.availablePermits()+" "+c.availablePermits()+" "+m.availablePermits()+" "+i);
if(i>10)
System.exit(0);
c.release();
m.release();
}
@Override
public void run() {
if(flag == 1) {
try {
while(true)
produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else {
try {
while (true)
consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(0);
Semaphore semaphore1 = new Semaphore(10);
Semaphore semaphore2 = new Semaphore(1);
for(int i = 0; i < 3; i++) {
FrameDemo f1 = new FrameDemo(1, semaphore, semaphore1, semaphore2);
Thread thread = new Thread(f1);
thread.setName("producer "+i);
thread.start();
}
for(int i = 0; i < 3; i++) {
FrameDemo f2 = new FrameDemo(0, semaphore, semaphore1, semaphore2);
Thread thread = new Thread(f2);
thread.setName("consumer "+i);
thread.start();
}
}
}
多生产多消费,生产最大值为10,生产消费线程各三个。
栅栏模式
在某一点上实现任务同步,只有所有任务都到达同步点后才能继续运行,一般借助CyclicBarrier类实现。package ThreadFrame.并行模式;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* @author mojiayi
* @date 2019-02-12 00:05
*/
public class ThreadDemo2 {
final int N;
final float[][] data;
final CyclicBarrier barrier;
class Worker implements Runnable {
int myRow;
Worker(int row) { myRow = row; }
public void run() {
int sum = 0;
for(int i = 0; i < data[myRow].length; i++){
sum += data[myRow][i];
}
System.out.println(barrier.isBroken());
System.out.println(Thread.currentThread().getName() + " " + sum);
try {
barrier.await();
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
}
public ThreadDemo2(float[][] matrix) {
data = matrix;
N = matrix.length;
//初始化CyclicBarrier
barrier = new CyclicBarrier(N, new Runnable() {
public void run() {
System.out.println("end"); //合并行
}
});
for (int i = 0; i < N; ++i)
new Thread(new Worker(i)).start();
}
public static void main(String[] args) {
float[][] floats = {{1,2,3},{2,3,4},{4,5,6}};
ThreadDemo2 demo2 = new ThreadDemo2(floats);
}
}