题目

实例化三个线程,一个线程打印a,一个线程打印b,一个线程打印c,三个线程同时执行,要求打印出10个连着的abc。

问题为三线程间的同步唤醒操作,主要的目的就是使程序按ThreadA->ThreadB->ThreadC->ThreadA循环执行三个线程

使用两个锁来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class RcSyncPrinter  {



private class Printer implements Runnable{

private final Object preLock;
private final Object lock;
private final char printChar;

public Printer(Object preLock, Object lock, char printChar) {
this.preLock = preLock;
this.lock = lock;
this.printChar = printChar;
}

@Override
public void run() {

for(int i=0;i<10;i++){
synchronized (preLock){
synchronized (lock){
System.out.println(printChar);
lock.notifyAll();
}
if(i < 10 - 1){
try {
// 通过preLock等待被唤醒
preLock.wait();

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}


}
}


public void test() throws InterruptedException {
final Object lockA = new Object();
final Object lockB = new Object();
final Object lockC = new Object();
Printer printerA = new Printer(lockC, lockA, 'A');
Printer printerB = new Printer(lockA, lockB, 'B');
Printer printerC = new Printer(lockB, lockC, 'C');
new Thread(printerA).start();
Thread.sleep(1000);
new Thread(printerB).start();
Thread.sleep(1000);
new Thread(printerC).start();
}


public static void main(String[] args) throws InterruptedException {

final RcSyncPrinter syncPrinter = new RcSyncPrinter();
syncPrinter.test();
}
}

使用一个锁和状态变量实现(推荐写法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public class RcSyncPrinter  {

//状态变量
private volatile int state=1;


private class Printer implements Runnable{


//打印锁
private final Object lock;
//打印状态
private final int printState;
private final int nextPrintState;
private final char printChar;

public Printer(Object lock, int printState, int nextPrintState, char printChar) {
this.lock = lock;
this.printState = printState;
this.nextPrintState = nextPrintState;
this.printChar = printChar;
}

@Override
public void run() {
synchronized (lock){

for(int i=0;i<10;i++){
while (state!=printState){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(printChar);
state=nextPrintState;
lock.notifyAll();
}

}


}


}
public void test() throws InterruptedException {
final Object lock = new Object();
Printer printerA = new Printer(lock, 1, 2, 'A');
Printer printerB = new Printer(lock, 2, 3, 'B');
Printer printerC = new Printer(lock, 3, 1, 'C');
new Thread(printerA).start();
//Thread.sleep(1000);
new Thread(printerB).start();
//Thread.sleep(1000);
new Thread(printerC).start();

}


public static void main(String[] args) throws InterruptedException {

final RcSyncPrinter syncPrinter = new RcSyncPrinter();
syncPrinter.test();
}
}

通过一个ReentrantLock和三个conditon实现(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public class RcSyncPrinter  {



private class Printer implements Runnable{

private ReentrantLock lock;
private Condition thisCondition;
private Condition nextCondition;
private final char printChar;

public Printer(ReentrantLock lock, Condition thisCondition, Condition nextCondition, char printChar) {
this.lock = lock;
this.thisCondition = thisCondition;
this.nextCondition = nextCondition;
this.printChar = printChar;
}

@Override
public void run() {

lock.lock();
try {
for (int i = 0; i < 10; i++) {
System.out.println(printChar);
nextCondition.signalAll();
if (i < 9) {
thisCondition.await();
}

}
}catch (InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}


}
}


public void test() throws InterruptedException {
final ReentrantLock lock = new ReentrantLock();
final Condition conditionA = lock.newCondition();
final Condition conditionB = lock.newCondition();
final Condition conditionC = lock.newCondition();
final Object lockA = new Object();
final Object lockB = new Object();
final Object lockC = new Object();
Printer printerA = new Printer(lock, conditionA,conditionB,'A');
Printer printerB = new Printer(lock, conditionB, conditionC,'B');
Printer printerC = new Printer(lock, conditionC, conditionA,'C');
new Thread(printerA).start();
Thread.sleep(1000);
new Thread(printerB).start();
Thread.sleep(1000);
new Thread(printerC).start();
}


public static void main(String[] args) throws InterruptedException {

final RcSyncPrinter syncPrinter = new RcSyncPrinter();
syncPrinter.test();
}
}