使用3个线程,1个线程打印X,一个线程打印Y,一个线程打印Z,同时执行连续打印10次"XYZ"
问题分析:核心是同一时间只有一个任务在执行,当前任务执行后把执行权交给特定的线程。我们把执行权抽象为资源。那么模型可以抽象为线程如果想要执行必须检查自己执行所需的的资源是不是满足,如果满足则去执行而且在持有资源期间资源不会被其他线程获取。首先我们想到锁是具有互持性的,我们可以通过这一特性去实现,接下来我们分别使用synchronized+notify方式Lock+Condition的方式和CAS的操作来实现
Lock+Condition condition
public class Test1 {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition conditionX = lock.newCondition();
Condition conditionY = lock.newCondition();
Condition conditionZ = lock.newCondition();
int time = 10;
Thread x = new Thread(new Task("X", time, lock, conditionX, conditionY));
Thread y = new Thread(new Task("Y", time, lock, conditionY, conditionZ));
Thread z = new Thread(new Task("Z", time, lock, conditionZ, conditionX));
x.start();
y.start();
z.start();
}
static class Task implements Runnable {
/**
* 实际执行任务内容
*/
private String name;
/**
* 任务执行次数
*/
private int time;
/**
*同步锁
*/
private Lock lock;
/**
* 等待资源
*/
private Condition wait;
/**
* 唤醒资源
*/
private Condition notify;
public Task(String name, int time, Lock lock, Condition wait, Condition notify) {
this.name = name;
this.time = time;
this.lock = lock;
this.wait = wait;
this.notify = notify;
}
@Override
public void run() {
int count = 0;
while (count < time) {
count++;
lock.lock();
System.out.println(name);
try {
notify.signal();
wait.await();
} catch (InterruptedException ignore) {
}
}
}
}
}
synchronized+notify方式
public class Sync {
private static int next = 0;
public static void main(String[] args) {
Object lock = new Object();
new Thread(new Task(0, lock, "X")).start();
new Thread(new Task(1, lock, "Y")).start();
new Thread(new Task(2, lock, "Z")).start();
}
static class Task implements Runnable {
private int t;
private Object lock;
private String name;
public Task(int t, Object lock, String name) {
this.t = t;
this.lock = lock;
this.name = name;
}
@Override
public void run() {
while (next < 30) {
synchronized (lock) {
if (next % 3 == t) {
System.out.println(name);
next++;
}
try {
lock.notifyAll();
lock.wait();
} catch (Exception ignore) {
}
}
}
}
}
}
CAS方式
public class Test1NoLock {
private static final int run=3;
public static void main(String[] args) throws InterruptedException {
AtomicInteger integer=new AtomicInteger(0);
new Thread(new Task("X",10,0,1,integer)).start();
new Thread(new Task("Y",10,1,2,integer)).start();
new Thread(new Task("Z",10,2,0,integer)).start();
}
static class Task implements Runnable{
private String name;
private int time;
private int expect;
private int update;
private AtomicInteger integer;
public Task(String name, int time,int expect, int update, AtomicInteger integer) {
this.name = name;
this.time=time;
this.expect = expect;
this.update = update;
this.integer = integer;
}
@Override
public void run() {
int count=0;
while (count<time) {
if (integer.compareAndSet(expect,run)){
count++;
System.out.println(name);
integer.compareAndSet(3,update);
}
}
}
}
}