一、內置鎖
- 同步:synchronized
- 協作:Object # wait/notify/notifyAll
public class PrintNumber {
/**
* 打印鎖,同一時刻僅有一個任務可以持有此鎖
*/
private static Object lock = new Object();
/**
* 計數器
*/
private static int counter = 1;
/**
* 計數器最大值
*/
private static final int MAX_COUNTER = 100;
public static void main(String args[]) {
// 奇數打印線程
Thread oddThread = new Thread() {
@Override
public void run() {
// 請求打印鎖
synchronized (lock) {
while (counter <= MAX_COUNTER) {
// counter爲奇數,打印counter並喚醒偶數打印線程
if (counter % 2 != 0) {
System.out.println("Thread1 : " + counter);
counter = counter + 1;
lock.notifyAll();
}
// counter爲偶數,掛起並等待偶數打印線程喚醒
else {
try {
lock.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
};
// 偶數打印線程
Thread evenThread = new Thread() {
@Override
public void run() {
// 請求打印鎖
synchronized (lock) {
while (counter <= MAX_COUNTER) {
// counter爲偶數,打印counter並喚醒奇數打印線程
if (counter % 2 == 0) {
System.out.println("Thread2 : " + counter);
counter = counter + 1;
lock.notifyAll();
}
// counter爲奇數,掛起並等待奇數打印線程喚醒
else {
try {
lock.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
};
oddThread.start();
evenThread.start();
}
}
二、顯式鎖
- 同步:lock/unlock
- 協作:Condition # await/signal/signalAll
public class PrintNumber {
/**
* 打印鎖,同一時刻僅有一個任務可以持有此鎖
*/
private static Lock lock = new ReentrantLock();
private static Condition oddCondition = lock.newCondition();
private static Condition evenCondition = lock.newCondition();
/**
* 計數器
*/
private static int counter = 1;
/**
* 計數器最大值
*/
private static final int MAX_COUNTER = 100;
public static void main(String args[]) {
// 奇數打印線程
Thread oddThread = new Thread() {
@Override
public void run() {
try {
// 請求打印鎖
lock.lock();
while (counter <= MAX_COUNTER) {
// counter爲奇數,打印counter並喚醒偶數打印線程
if (counter % 2 != 0) {
System.out.println("Thread1 : " + counter);
counter = counter + 1;
evenCondition.signalAll();
}
// counter爲偶數,掛起並等待偶數打印線程喚醒
else {
try {
oddCondition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
} finally {
// 釋放打印鎖
lock.unlock();
}
}
};
// 偶數打印線程
Thread evenThread = new Thread() {
@Override
public void run() {
try {
// 請求打印鎖
lock.lock();
while (counter <= MAX_COUNTER) {
// counter爲偶數,打印counter並喚醒奇數打印線程
if (counter % 2 == 0) {
System.out.println("Thread2 : " + counter);
counter = counter + 1;
oddCondition.signalAll();
}
// counter爲奇數,掛起並等待奇數打印線程喚醒
else {
try {
evenCondition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
} finally {
// 釋放打印鎖
lock.unlock();
}
}
};
oddThread.start();
evenThread.start();
}
}