線程通信有三種方式:
(1)synchronized+wait+notify等待喚醒方式
(2)Condition.await()方法
(3)阻塞隊列
下面根據兩道面試題分別實現線程之間的通信
(1)搜狐暢遊筆試題,以第一種方式實現
創建兩個線程,其中一個輸出1-52,另外一個輸出A-Z。輸出格式要求:12A 34B 56C 78D 依次類推
package com.interview.main;
//創建兩個線程,其中一個輸出1-52,另外一個輸出A-Z。輸出格式要求:12A 34B 56C 78D 依次類推
public class Main {
private static final Object lock = new Object();
public static void main(String[] args) {
PrintNumber pn = new PrintNumber(lock);
PrintChar pc = new PrintChar(lock);
Thread t1 = new Thread(pn);
Thread t2 = new Thread(pc);
t1.start();
t2.start();
}
}
class PrintNumber implements Runnable {
private Object lock;
PrintNumber(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
for (int i = 1; i <= 52; i++) {
System.out.print(i);
if (i % 2 == 0) {// 線程暫停
// 喚醒其他線程
lock.notifyAll();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class PrintChar implements Runnable {
private Object lock;
PrintChar(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
for (int i = 0; i < 26; i++) {
char ch = (char) (i + 65);
if (ch != 'Z') {
System.out.print(ch + " ");
// 喚醒其他線程
lock.notifyAll();
// 線程暫停
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
// 喚醒其他線程
lock.notifyAll();
System.out.print(ch);
}
}
}
}
}
(2)三個線程輪流執行順序打印ABC,依次是ABCABCABC......
使用ReentantLock+Condition
package com.interview.main;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//三個線程輪流執行順序打印ABC,依次是ABCABCABC......
public class Main {
public static void main(String[] args) {
printABC print = new printABC();
new Thread(new Runnable() {
@Override
public void run() {
print.PrintA();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
print.PrintB();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
print.PrintC();
}
}).start();
}
}
class printABC {
private static final Lock lock = new ReentrantLock();
private Condition lockA = lock.newCondition();
private Condition lockB = lock.newCondition();
private Condition lockC = lock.newCondition();
int flg = 0;// 用於切換
public void PrintA() {
lock.lock();
try {
while (true) {
while (flg != 0) {// 不輸出
lockA.await();
} // 輸出
System.out.print("A");
flg = 1;
lockB.signal();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void PrintB() {
lock.lock();
try {
while (true) {
while (flg != 1) {// 不輸出
lockB.await();
} // 輸出
System.out.print("B");
flg = 2;
lockC.signal();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void PrintC() {
lock.lock();
try {
while (true) {
while (flg != 2) {// 不輸出
lockC.await();
} // 輸出
System.out.print("C");
Thread.sleep(1000);
flg = 0;
lockA.signal();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}