1. 利用synchronized
思路:
打印A时,必须先拿到 B,C锁, 打印完了之后,释放A锁,然后打印B的线程拿到A锁后就可以打印B,依次循环。
public class MythreadPrinter implements Runnable {
private String name;
private Object prev;
private Object self;
@Override
public void run() {
int count = 3;
while (count>0){
synchronized (prev){
synchronized (self){
System.out.println(name);
count--;
self.notify();
}
try {
prev.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws Exception{
Object a = new Object();
Object b = new Object();
MythreaPrinter pa = new MythreaPrinter("A",b,a);
MythreaPrinter pb = new MythreaPrinter("B",a,b);
new Thread(pa).start();
Thread.sleep(100);
new Thread(pb).start();
Thread.sleep(100);
}
}
2.利用lock
public class MythreadPrinter_lock {
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition();
public String cur_name = "A";
public static void main(String[] args) {
MythreadPrinter_lock myPrinter = new MythreadPrinter_lock();
ExecutorService es = Executors.newFixedThreadPool(3);
es.submit(myPrinter.new PrinterA());
es.submit(myPrinter.new PrinterB());
es.submit(myPrinter.new PrinterC());
es.shutdown();
}
public class PrinterA implements Runnable{
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
lock.lock();
try {
while(cur_name != "A"){
try {
conditionA.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("第"+i+"次打印"+cur_name);
cur_name = "B";
conditionB.signal();
}catch (Exception e){
}finally {
lock.unlock();
}
}
}
}
public class PrinterB implements Runnable{
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
lock.lock();
try {
while(cur_name != "B"){
try {
conditionB.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("第"+i+"次打印"+cur_name);
cur_name = "C";
conditionC.signal();
}catch (Exception e){
}finally {
lock.unlock();
}
}
}
}
public class PrinterC implements Runnable{
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
lock.lock();
try {
while(cur_name != "C"){
try {
conditionC.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("第"+i+"次打印"+cur_name);
cur_name = "A";
conditionA.signal();
}catch (Exception e){
}finally {
lock.unlock();
}
}
}
}
}