3 线程间通信
线程间通信的模型有两种:共享内存和消息传递,以下方式都是基于这两种模型来实现的。我们来基于一道常见的面试题目来分析
场景–两个线程,一个线程对当前数值加1,另一个线程对当前数值减1,要求用线程间通信
3.1 synchronized方案
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
| public class TestVolatile { public static void main(String[] args) { DemoClass demoClass = new DemoClass(); new Thread(()->{ for (int i=0;i<5;i++){ demoClass.increment(); } }).start();
new Thread(()->{ for (int i = 0; i < 5; i++) { demoClass.decrement(); } }).start();
} }
class DemoClass{
private int number = 0;
public synchronized void increment(){ try { while (number !=0 ){ this.wait(); } number ++; System.out.println("---"+Thread.currentThread().getName()+"加1的结果为:"+number+"---"); notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } }
public synchronized void decrement(){ try { while (number ==0 ){ this.wait(); } number --; System.out.println("---"+Thread.currentThread().getName()+"减1的结果为:"+number+"---"); notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } }
|
3.2 Lock方案
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
| class DemoClass{ private int number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void increment(){ try { lock.lock(); while (number !=0){ condition.await(); } number ++; System.out.println("---"+Thread.currentThread().getName()+"加1的结果为:"+number+"---"); condition.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); }
}
public void decrement(){ try { lock.lock(); while (number ==0){ condition.await(); } number --; System.out.println("---"+Thread.currentThread().getName()+"减1的结果为:"+number+"---"); condition.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); }
}
}
|
3.4 线程间定制化通信
3.4.1 案例介绍
==问题:A线程打印五次A,B线程打印10次B,C线程打印15次C,按照此顺序循环10轮==
3.4.2 实现流程
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 69 70 71 72 73
| class DemoClass{
private String CODE = "A";
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition();
public void printA(){ try { lock.lock(); if (!CODE.equals("A")){ conditionA.await(); } for (int i = 0; i < 5; i++) { System.out.println("A"); } CODE = "B"; conditionB.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); }
}
public void printB(){ try { lock.lock(); if (!CODE.equals("B")){ conditionB.await(); } for (int i = 0; i < 10; i++) { System.out.println("B"); } CODE = "C"; conditionC.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); }
}
public void printC(){ try { lock.lock(); if (!CODE.equals("C")){ conditionC.await(); } for (int i = 0; i < 15; i++) { System.out.println("C"); } CODE = "A"; conditionA.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }
|
sychronized实现同步的基础:Java中的每一个对象都可以作为锁,具体表现为以下三种方式。