使用多线程交替打印123123123…
方法一:使用Lock lock = new ReentrantLock();
`lock.lock();``lock.unlock();`
package junhaox.cn.interview;import java.io.File;import java.io.FileNotFoundException;import java.io.PrintStream;import java.io.PrintWriter;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/*** 多线程交替打印123123123...* 方法1* @author wjh**/public class LoopPrint {// 从1 开始打印int num = 1;Lock lock = new ReentrantLock();// 三个线程的通知Condition condition1 = lock.newCondition();Condition condition2 = lock.newCondition();Condition condition3 = lock.newCondition();public void print1() {// 加锁防止多个线程同时操作numlock.lock();try {if (num != 1) {condition1.await();}System.out.println(Thread.currentThread().getName()+num);// Thread.sleep(1000);// 通知线程2num = 2;condition2.signal();} catch (InterruptedException e) {e.printStackTrace();}finally {// 使用完毕记得释放锁lock.unlock();}}public void print2() {// 加锁防止多个线程同时操作numlock.lock();try {if (num != 2) {condition2.await();}System.out.println(Thread.currentThread().getName()+num);// Thread.sleep(1000);// 通知线程3num = 3;condition3.signal();} catch (InterruptedException e) {e.printStackTrace();}finally {lock.unlock();}}public void print3() {// 加锁防止多个线程同时操作numlock.lock();try {if (num != 3) {condition3.await();}System.out.println(Thread.currentThread().getName()+num);// Thread.sleep(1000);// 通知线程1num = 1;condition1.signal();} catch (InterruptedException e) {e.printStackTrace();}finally {lock.unlock();}}public static void main(String[] args) {LoopPrint print = new LoopPrint();// System.out.println(111);new Thread(()->{while (true) {print.print1();}}).start();new Thread(()->{while (true) {print.print2();}}).start();new Thread(()->{while (true) {print.print3();}}).start();}}
方法二:使用synchronized wait()和notify()
package junhaox.cn.interview;import java.io.FileNotFoundException;import java.io.PrintStream;/*** 多线程交替打印123123123...* 方法1* @author wjh**/public class SnyLoopPrint {int num = 1;synchronized public void print1() {try {if (num != 1) {System.out.println("线程1进入等待");this.wait();}else {System.out.println(Thread.currentThread().getName()+num);// Thread.sleep(1000);// 通知线程2num = 2;this.notifyAll();}} catch (InterruptedException e) {e.printStackTrace();}}synchronized public void print2() {try {if (num != 2) {System.out.println("线程2进入等待");this.wait();}else {System.out.println(Thread.currentThread().getName()+num);// Thread.sleep(1000);// 通知线程3num = 3;this.notifyAll();}} catch (InterruptedException e) {e.printStackTrace();}}synchronized public void print3() {try {if (num != 3) {System.out.println("线程3进入等待");this.wait();}else {System.out.println(Thread.currentThread().getName()+num);// Thread.sleep(1000);// 通知线程1num = 1;this.notifyAll();}} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {SnyLoopPrint print = new SnyLoopPrint(1);// System.out.println(111);new Thread(()->{while (true) {print.print1();}}).start();new Thread(()->{while (true) {print.print2();}}).start();new Thread(()->{while (true) {print.print3();}}).start();}}
注意:使用方法一和二时一定是先修改num的值在进行通知
方法三:使用信号量的方式Semaphore sm1 = new Semaphore(1);
package junhaox.cn.interview;import java.util.concurrent.Semaphore;public class SemaphoreDemo {//Semaphore sm1 = new Semaphore(1);Semaphore sm2 = new Semaphore(0);Semaphore sm3 = new Semaphore(0);private void print(int value, Semaphore current, Semaphore next) {try {// 获取管道(总共只有1个),用完就停current.acquire(1);System.out.println(Thread.currentThread().getName()+"----"+value);Thread.sleep(1000);// 释放一个管道,谁释放谁拿next.release(1);} catch (InterruptedException e) {e.printStackTrace();}}public void print1() {print(1, sm1, sm2);}public void print2() {print(2, sm2, sm3);}public void print3() {print(3, sm3, sm1);}public static void main(String[] args) {SemaphoreDemo sd = new SemaphoreDemo();new Thread(()->{while (true) {sd.print1();}}).start();new Thread(()->{while (true) {sd.print2();}}).start();new Thread(()->{while (true) {sd.print3();}}).start();}}
