在面試中遇到了這個問題 ,這個問題主要考面試者的多線程相關的知識,包括但不限於wait/notify 鎖 Volatile變量3個方面。
3個線程 循環打印ABC 10次
第一種實現 Volatile 實現 依靠共同的state變量來保證 需要輪詢
public class ThreadForDemo {
private static volatile int threestate=0;
static class MyThread extends Thread{
int state;
MyThread(int state){
this.state = state;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
while (true){
if(threestate%3==state){
break;
}
}
System.out.println((char)('A'+state));
threestate++;
}
}
}
public static void main(String[] args) {
MyThread one = new MyThread(0);
MyThread two = new MyThread(1);
MyThread three = new MyThread(2);
one.start();
two.start();
three.start();
}
}
第二種實現 基於 wait/notify范式來實現
wait/ notify 基本上是這樣的
while(條件不成立){
obj.wait();
}
obj.notifyall();
具體實現如下 利用共同的obj 來達到控制的目的 速度比較慢
public class ThreadForDemo {
static class MyThread implements Runnable {
Printer printer;
char words='A';
public MyThread(Printer printer, char words) {
this.printer = printer;
this.words = words;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (printer){
while(words!= printer.getWords()){
try {
printer.wait();
}catch (Exception e){
e.printStackTrace();
}
}
printer.print();
printer.next();
printer.notifyAll();
}
}
}
}
static class Printer {
char words = 'A';
void print(){
System.out.println(words);
}
void next(){
switch (words){
case 'A': words = 'B';
break;
case 'B': words = 'C';
break;
case 'C': words = 'A';
break;
}
}
char getWords(){
return words;
}
}
public static void main(String[] args) {
Printer printer = new Printer();
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.execute(new MyThread(printer,'A'));
executorService.execute(new MyThread(printer,'B'));
executorService.execute(new MyThread(printer,'C'));
executorService.shutdown();
}
}
利用 JUC 中的condition 來完成 和 wait / notify方法差不多的效果 區別在與Condition 可以創建多個
public class ThreadForDemo {
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
int commonstate = 0;
class MyThread implements Runnable{
int state;
public MyThread(int state) {
this.state = state;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
lock.lock();
try {
switch (state){
case 0 :{
while (commonstate!=0){
conditionA.await();
}
System.out.println((char)('A'+state));
commonstate=1;
conditionB.signal();
break;
}
case 1:{
while (commonstate!=1){
conditionB.await();
}
System.out.println((char)('A'+state));
commonstate=2;
conditionC.signal();
break;
}
case 2:{
while (commonstate!=2){
conditionC.await();
}
System.out.println((char)('A'+state));
commonstate=0;
conditionA.signal();
break;
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
ThreadForDemo threadForDemo = new ThreadForDemo();
executorService.execute(threadForDemo.new MyThread(0));
executorService.execute(threadForDemo.new MyThread(1));
executorService.execute(threadForDemo.new MyThread(2));
executorService.shutdown();
}
}