多个线程想要执行同一同步代码块,则需要先抢占锁资源,要实现顺序输出ABC还要对同步代码块实现顺序访问,本文将采用synchronized、Lock-Condition、Semaphore的方式实现。如果不了解Lock-Conditionk和Semaphore请先浏览学习我后续发布的JUC章节中相关知识点。
synchronized方式
public class ABCsynchronizedDemo {
public static void main(String[] args) {
ABC demo3 = new ABC();
new Thread(new Runnable() {
@Override
public void run() {
try {
demo3.test1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
demo3.test2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "B").start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
demo3.test3();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "C").start();
}
}
class ABC {
private volatile int i = 0;
public synchronized void test1() throws InterruptedException {
while (true) {
while (i != 0) {
wait();
}
System.out.println("A");
i = 1;
notifyAll();
}
}
public synchronized void test2() throws InterruptedException {
while (true) {
while (i != 1) {
wait();
}
System.out.println("B");
i = 2;
notifyAll();
}
}
public synchronized void test3() throws InterruptedException {
while (true) {
while (i != 2) {
wait();
}
System.out.println("C");
i = 0;
notifyAll();
}
}
}
Lock-Condition
public class ABCConditionDemo {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
final int[] i = {0};
int[] count = {0};
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
for (int j = 0; j < 20; j++) {
while (i[0] != 0) {
conditionA.await();
}
System.out.println("A");
i[0] = 1;
conditionB.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
for (int j = 0; j < 20; j++) {
while (i[0] != 1) {
conditionB.await();
}
System.out.println("B");
i[0] = 2;
conditionC.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
for (int j = 0; j < 20; j++) {
while (i[0] != 2) {
conditionC.await();
}
System.out.println("C");
System.out.println("-----------------------" + count[0]++);
i[0] = 0;
conditionA.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}).start();
}
}
Semaphore
public class ABCSemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphoreA = new Semaphore(1);
Semaphore semaphoreB = new Semaphore(0);
Semaphore semaphoreC = new Semaphore(0);
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
semaphoreA.acquire();
System.out.println("A");
semaphoreB.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
semaphoreB.acquire();
System.out.println("B");
semaphoreC.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
semaphoreC.acquire();
System.out.println("C");
semaphoreA.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}