java实现交替打印的四种方法

交替打印就是要实现线程间通信,有两种方式:

1Object对象中的wait和notify(因为是交替打印,只需唤醒一个线程,所以不需要notifyAll)

 1 package com.nmcc.thread;
 2 
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 
 6 /**
 7  * TODO
 8  *
 9  * @author nmcc
10  * @version V1.0
11  * @date 2021-08-24 08:49
12  *
13  */
14 public class SyncRunTwo {
15 
16     public static Object a_o = new Object();
17     public static Object b_o = new Object();
18     public static Object c_o = new Object();
19 
20     public static void main(String[] args) throws InterruptedException {
21         ExecutorService executor = Executors.newFixedThreadPool(3);
22         executor.execute(new BuszThread("C", c_o, b_o));
23         executor.execute(new BuszThread("B", b_o, a_o));
24         executor.execute(new BuszThread("A", a_o, c_o));
25         Thread.sleep(1000);
26 
27         synchronized (c_o){
28             c_o.notify();
29         }
30     }
31 
32     public static class BuszThread implements Runnable {
33 
34         private String name;
35         private Object take;
36         private Object waitFor;
37         public BuszThread(String name, Object take, Object waitFor){
38             this.name = name;
39             this.take = take;
40             this.waitFor = waitFor;
41         }
42         @Override
43         public void run() {
44             System.out.println(name + " 开始执行");
45 
46                 while (true) {
47                     synchronized (waitFor) {
48                         try {
49                             System.out.println(name + " 开始等待它需要的条件");
50                             waitFor.wait();
51                             System.out.println(name + " 获得了它需要的等待条件");
52                             Thread.sleep(1000);
53                             System.out.println(name + " 执行完成,并释放它持有的等待条件");
54                         } catch (InterruptedException e) {
55                             e.printStackTrace();
56                         }
57                     }
58 
59                     synchronized (take){
60                         take.notify();
61                     }
62             }
63 
64         }
65     }
66 }

 

2使用lock中的Condition

 1 package com.nmcc.thread;
 2 
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.atomic.AtomicBoolean;
 6 import java.util.concurrent.locks.Condition;
 7 import java.util.concurrent.locks.Lock;
 8 import java.util.concurrent.locks.ReentrantLock;
 9 
10 /**
11  * TODO
12  *
13  * @author nmcc
14  * @version V1.0
15  * @date 2021-08-24 08:49
16  *
17  */
18 public class SyncRun {
19     private static Lock lock = new ReentrantLock(false);
20     private static Condition a_c = lock.newCondition();
21     private static Condition b_c = lock.newCondition();
22     private static Condition c_c = lock.newCondition();
23 
24     public static void main(String[] args) throws InterruptedException {
25         ExecutorService executor = Executors.newFixedThreadPool(3);
26         executor.execute(new BuszThread("C", c_c, b_c));
27         executor.execute(new BuszThread("B", b_c, a_c));
28         executor.execute(new BuszThread("A", a_c, c_c));
29         Thread.sleep(1000);
30         lock.lock();
31         try {
32             c_c.signal();
33         } finally {
34             lock.unlock();
35         }
36 
37 
38     }
39 
40     public static class BuszThread implements Runnable {
41 
42         private String name;
43         private Condition take;
44         private Condition waitFor;
45         private AtomicBoolean hasRun = new AtomicBoolean(false);
46         public BuszThread(String name, Condition take, Condition waitFor){
47             this.name = name;
48             this.take = take;
49             this.waitFor = waitFor;
50         }
51         @Override
52         public void run() {
53             System.out.println(name + " 开始执行");
54             while (true){
55                 lock.lock();
56                 try {
57                     System.out.println(name + " 开始等待它需要的条件");
58                     waitFor.await();
59                     System.out.println(name + " 获得了它需要的等待条件");
60                     Thread.sleep(1000);
61                     System.out.println(name + " 执行完成,并释放它持有的等待条件");
62                     take.signal();
63 
64                 } catch (InterruptedException e) {
65                     e.printStackTrace();
66                 }finally {
67                     lock.unlock();
68                 }
69             }
70         }
71     }
72 }

 

这两种方式,首先都需要获取到锁,然后等待他需要的前置条件,前置条件执行后,轮到他执行,然后它再去释放他持有的前置条件,

Condition是一个lock实例出来的,他们获取的都市一个lock的锁,而如果要调用object的wait和notify方法,首先要获取对应的object的锁。

 

3使用原子变量,这种方式其实不是线程间通信,他是用原子变量的比较并替换原子,让两个线程去交替的替换成功。

package com.nmcc.thread;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 两个线程交替打印奇偶数
 *
 * @author nmcc
 * @version V1.0
 * @date 2021-09-02 16:53
 */
public class SyncPrint {

   private static AtomicInteger num = new AtomicInteger(0);

    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2,2,60, TimeUnit.SECONDS,new LinkedBlockingQueue<>());

        executor.execute(new Printer(num, 0, "A"));
        executor.execute(new Printer(num, 1, "B"));
    }

   public static class Printer implements Runnable{
       private AtomicInteger num;
       private Integer start;
       private Integer step = 1;
       private String name;

       public Printer(AtomicInteger num, Integer start, String name) {
           this.num = num;
           this.start = start;
           this.name = name;
       }

       @Override
       public void run() {
           try {
               while (true){
                   Integer update = start + step;
                   Thread.sleep(1000);
                   if (num.compareAndSet(start, update)){
                       System.out.println(name + " say: " + update);
                       start +=2;
                       Thread.sleep(1000);
                   }
               }
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
   }
}

 

4使用阻塞队列

 1 package com.nmcc.thread;
 2 
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.LinkedBlockingQueue;
 6 
 7 /**
 8  * TODO
 9  *
10  * @author nmcc
11  * @version V1.0
12  * @date 2021-08-24 08:49
13  *
14  */
15 public class SyncRunThree {
16 
17     public static LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(1);
18     public static void main(String[] args) throws InterruptedException {
19         ExecutorService executor = Executors.newFixedThreadPool(3);
20         executor.execute(new BuszThread("C", queue));
21         executor.execute(new BuszThread("B", queue));
22         executor.execute(new BuszThread("A", queue));
23         Thread.sleep(1000);
24         queue.put(1);
25     }
26 
27     public static class BuszThread implements Runnable {
28 
29         private String name;
30         private LinkedBlockingQueue<Integer> queue;
31         public BuszThread(String name, LinkedBlockingQueue<Integer> queue){
32             this.name = name;
33             this.queue = queue;
34         }
35         @Override
36         public void run() {
37             System.out.println(name + " 开始执行");
38 
39                 while (true) {
40                     try {
41                         System.out.println(name + " 准备获取");
42                         Integer num = queue.take();
43                         System.out.println(name + " 获取到:" + num);
44                         queue.put(++num);
45                         Thread.sleep(1000);
46                     } catch (InterruptedException e) {
47                         e.printStackTrace();
48                     }
49                 }
50             }
51 
52     }
53 }

 

public static class BuszThread implements Runnable {

private String name;
private Condition take;
private Condition waitFor;
private boolean isFirst;
private AtomicBoolean hasRun = new AtomicBoolean(false);
public BuszThread(String name, Condition take, Condition waitFor, boolean isFirst){
this.name = name;
this.take = take;
this.waitFor = waitFor;
this.isFirst = isFirst;
}
@Override
public void run() {
System.out.println(name + " 开始执行");
while (true){
lock.lock();
try {
System.out.println(name + " 开始等待它需要的条件");
waitFor.await();
System.out.println(name + " 获得了它需要的等待条件");
Thread.sleep(1000);
System.out.println(name + " 执行完成,并释放它持有的等待条件");
take.signal();

} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
}
posted @ 2021-09-03 10:03  龌龊猫  阅读(1160)  评论(0编辑  收藏  举报