1、线程通信-交替操作sync实现
变量初始值为0
a线程对变量进行++操作后,通知b线程对变量进行—操作
b线程对变量进行—操作后,通知a线程对变量进行++操作
使用synchronized与Lock两种方式实现。
synchronized代码实现:
class STicket{private int target=0;public synchronized void incr(){if(target!=0){try {//等待其他线程进行操作this.wait();} catch (InterruptedException e) {e.printStackTrace();}}target++;System.out.println(Thread.currentThread().getName()+"::"+target);//操作完毕后,唤醒其他线程进行操作this.notifyAll();}public synchronized void decr(){if(target!=1){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}target--;System.out.println(Thread.currentThread().getName()+"::"+target);this.notifyAll();}}public class SyncTest {public static void main(String[] args) {STicket ticket=new STicket();new Thread(()->{for (int i=0;i<10;i++){ticket.incr();}},"线程1").start();new Thread(()->{for (int i=0;i<10;i++){ticket.decr();}},"线程2").start();}}
2、线程通信synchronized虚假唤醒
创建线程3:对target进行++操作
创建线程4:对target进行—操作
虚假唤醒情况说明:当线程1对target操作完毕后target=1,恰好此时线程3抢到执行权,此时线程3进入等待状态target=1,此时线程2抢到执行权对target进行操作后target=0,线程1再次抢到执行权操作完毕后唤醒线程target=1,刚好被线程3抢到执行权进行++后,此时target=2,同理—操作也如此。
解决方案:将 if 判断修改为 while 循环
while(target!=0){this.wait();//异常处理省略}while(target!=1){this.wait();}
3、线程通信-交替操作Lock实现
class Share {private int target = 0;private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();public void incr() throws InterruptedException {lock.lock();try {while (target != 0) {//等待其他线程进行操作condition.await();}target++;System.out.println(Thread.currentThread().getName() + "::" + target);//唤醒其他线程condition.signalAll();} finally {lock.unlock();}}public void decr() throws InterruptedException {lock.lock();try {while (target != 1) {condition.await();}target--;System.out.println(Thread.currentThread().getName() + "::" + target);condition.signalAll();} finally {lock.unlock();}}}public class LockDemo {public static void main(String[] args) {Share share = new Share();new Thread(() -> {for (int i = 0; i < 10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}}, "线程1").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}}, "线程2").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}}, "线程3").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}}, "线程4").start();}}
