在面试中遇到了这个问题 ,这个问题主要考面试者的多线程相关的知识,包括但不限于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();
}
}