算法与刷题|四种方式实现2个线程交互打印从1到100的奇偶数《八》

1. 利用volatile状态标志实现(自己写的,哈哈)

package duoxiancheng.print; public class PrintBai { /* 1. 任务:两个线程交替的打印从1到100里面的奇数和偶数 2. 但是你如果查看打印结果会发现,其实当第一个线程运行的时候 另一个线程也没有闲着,也会在else里面打印,只是没有进入到它的if里面 3. 这样的方式可以满足交替打印的目的,但是效率不是很高,不推荐,我们再去尝试一下其它的方式 4. volatile 是必须要加的*/public static int i = 1; public static volatile boolean flag = false; public static void test() { new Thread(() -> { while (i <= 100) { if (flag == false) { System.out.println(Thread.currentThread().getName() + i); i++; flag = true; }else { //System.out.println("奇"+i); } } }, "奇数线程:").start(); new Thread(() -> { while (i <= 100) { if (flag == true) { System.out.println(Thread.currentThread().getName() + i); i++; flag = false; }else { //System.out.println("偶"+i); } } }, "偶数线程:").start(); }public static void main(String[] args) { test(); } }

2. 利用synchronized和线程通信
public class PrintOneToHundred2 {public static void main(String[] args) throws Exception {AtomicInteger ct = new AtomicInteger(0); Thread a = new Thread(() -> { try { while (ct.get() < 100) { synchronized (ct) { System.out.println(Thread.currentThread().getName() + " :" + ct.incrementAndGet()); ct.notify(); ct.wait(); } } } catch (InterruptedException e) {} finally {}}, "odd"); Thread b = new Thread(() -> { try { while (ct.get() < 100) { synchronized (ct) { System.out.println(Thread.currentThread().getName() + " :" + ct.incrementAndGet()); ct.notify(); ct.wait(); } } } catch (InterruptedException e) {} finally {} }, "even"); a.start(); a.join(10); b.start(); }}

3. 利用线程锁
package duoxiancheng.print; import java.util.concurrent.locks.ReentrantLock; /** * Created by szh on 2019/1/17. * * @author szh */ public class PrintOneToHundred {static volatile int ct = 1; public static void main(String[] args) {ReentrantLock reentrantLock = new ReentrantLock(); Thread a = new Thread(() -> { try { while (!(ct >= 100)) { while ((ct%2==0)){ reentrantLock.lock(); ct++; System.out.println(Thread.currentThread().getName() + " " + ct); reentrantLock.unlock(); } } } finally {} }, "odd"); Thread b = new Thread(() -> { try { while (!(ct >= 100)) { while ((ct%2==1)){ reentrantLock.lock(); ct++; System.out.println(Thread.currentThread().getName() + " " + ct); reentrantLock.unlock(); } } } finally {} }, "even"); a.start(); b.start(); }}

利用公平锁
package duoxiancheng.reentrantLock; import java.util.concurrent.locks.ReentrantLock; public class FairLock implements Runnable{ // 必须是true,如果是false,那就是不公平的,不公平就不会出现交替打印的结果了 //因为你不知道一个线程什么时候会释放它的锁 public static ReentrantLock fairLock = new ReentrantLock(true); static volatile int ct = 0; public void run() { while (ct<100) { try { fairLock.lock(); System.out.println(Thread.currentThread().getName()+",获得锁!"+ct); ct++; }finally { fairLock.unlock(); System.out.println(Thread.currentThread().getName()+",释放锁!"+ct); } } } public static void main(String[] args) { FairLock fairLock = new FairLock(); Thread t1 = new Thread(fairLock, "线程1"); Thread t2 = new Thread(fairLock, "线程2==="); t1.start(); t2.start(); } }

    推荐阅读