遇到的一些多线程案例(1)

题目:使用多线程 将["123","456","789"] 这种字符串数组处理为["147","258","369"]形式输出

 1 public String[] formart(String[] numbers) {
 2         ExecutorService ex = Executors.newFixedThreadPool(3);
 3         int size = numbers.length;
 4         String[][] pp = new String[size][ size];
 5         for (int i = 0; i < numbers.length; i++) {
 6             int k = i;
 7             ex.execute(() -> {
 8                 System.out.println(Thread.currentThread().getName()+" 开始处理--------");
 9                 char[] chars = numbers[k].toCharArray();
10                 for (int j = 0; j < chars.length; j++) {
11                     pp[ j % size ][k] = String.valueOf(chars[ j ]);
12                 }
13             });
14         }
15         ex.shutdown();
16         String[] result = new String[size];
17         for (int i = 0; i <pp.length ; i++) {
18             StringBuffer sb = new StringBuffer();
19             for (String s : pp[i]) {
20                 sb.append(s);
21             }
22             result[i] = sb.toString();
23         }
24         return result;
25     }

 

问题:题目用让四个线程循环有序输出1,2,3,4    这儿有次测试发现如果index不用volatile修饰会卡死,详细说明请看:https://www.cnblogs.com/hetutu-5238/p/12188316.html

 1 public class Demo2 {
 2 
 3     public static  volatile  int index = 0;
 4     public static void main(String[] args) {
 5         ThreadTest t1 = new ThreadTest("线程1" , 0);
 6         ThreadTest t2 = new ThreadTest("线程2" , 1);
 7         ThreadTest t3 = new ThreadTest("线程3" , 2);
 8         ThreadTest t4 = new ThreadTest("线程4" , 3);
 9         t1.start();
10         t2.start();
11         t3.start();
12         t4.start();
13 
14     }
15     static class ThreadTest extends Thread {
16         private int i;
17         public ThreadTest(String name , int i) {
18             super(name);
19             this.i = i;
20         }
21         @Override
22         public void run() {
23             while ( true ) {
24                 if ( (index & 3) == i ) {
25                     System.out.println(Thread.currentThread().getName() + ":" + (i+1));
26                     index++;
27                 }
28             }
29         }
30 
31     }
32 
33 }

 

问题:有多个线程,代表的是行使的汽车,写一个红绿灯函数,等红灯亮时把所有的汽车线程都暂停,当绿灯亮时所有线程都启动起来

这儿先贴一个看到的比较好的答案,自己利用AQS实现锁,让所有汽车均可以通过这个锁类来控制通行。引用地址:https://segmentfault.com/q/1010000016621995/a-1020000016628980

这儿实现了tryAcquireShared方法通过判断红绿灯来决定是让其获取锁。这儿注意是实现共享锁方法所以下面的汽车均可以获得这把锁

 

  1 import java.io.BufferedReader;
  2 import java.io.IOException;
  3 import java.io.InputStreamReader;
  4 import java.util.ArrayList;
  5 import java.util.Collection;
  6 import java.util.List;
  7 import java.util.concurrent.locks.AbstractQueuedSynchronizer;
  8 
  9 /**
 10  * 交通信号灯实现
 11  * 等红灯亮时把所有汽车线程都暂停,当绿灯亮时把所有线程都启动起来
 12  * @author ccr at 20181008
 13  */
 14 public class TrafficLightLatch {
 15     private final class Sync extends AbstractQueuedSynchronizer {
 16         @Override
 17         protected int tryAcquireShared(int ignored) {
 18             return redLight == 0 ? 1 : -1;
 19         }
 20 
 21         @Override
 22         protected boolean tryReleaseShared(int arg) {
 23             return true;
 24         }
 25     }
 26 
 27     /**
 28      * 信号灯状态,非0代表红灯,0代表绿灯
 29      */
 30     volatile private int redLight;
 31 
 32     private Sync sync;
 33 
 34     /**
 35      * 初始化
 36      * @param redLight 初始红绿灯状态,非0代表红灯,0代表绿灯
 37      */
 38     public TrafficLightLatch(int redLight) {
 39         this.redLight = redLight;
 40         sync = new Sync();
 41     }
 42 
 43     /**
 44      * 红灯则等待,绿灯则直接通过
 45      * @throws InterruptedException
 46      */
 47     public void await() throws InterruptedException {
 48         sync.acquireSharedInterruptibly(1);
 49     }
 50 
 51     /**
 52      * 切换为红灯
 53      */
 54     public void switchRed(){
 55         this.redLight = 1;
 56     }
 57 
 58     /**
 59      * 切换为绿灯
 60      */
 61     public void switchGreen() {
 62         this.redLight = 0;
 63         sync.releaseShared(0);
 64     }
 65 
 66     /**
 67      * 是否有线程等待
 68      */
 69     public boolean hasQueuedThreads() {
 70         return sync.hasQueuedThreads();
 71     }
 72 
 73     /**
 74      * 等待中的线程
 75      * @return Collection
 76      */
 77     public Collection<Thread> getQueuedThreads() {
 78         return sync.getQueuedThreads();
 79     }
 80 
 81     public String getLightColor() {
 82         return redLight == 0 ? "绿灯" : "红灯";
 83     }
 84 
 85     //测试用例
 86     public static void main(String[] args) throws IOException, InterruptedException {
 87         //初始化交通信号灯为红灯
 88         TrafficLightLatch light = new TrafficLightLatch(1);
 89         List<Thread> threads = new ArrayList<>();
 90         //10个线程模拟车辆
 91         for (int i = 0; i < 10; i++) {
 92             Thread thread = new Thread(() -> {
 93                 while (!Thread.currentThread().isInterrupted()) {
 94                     //System.out.println(String.format("%s: 信号灯-%s",Thread.currentThread().getName(),light.getLightColor()));
 95                     try {
 96                         //绿灯直接通行,红灯阻塞等待
 97                         light.await();
 98                     } catch (InterruptedException e) {
 99                         //恢复中断
100                         Thread.currentThread().interrupt();
101                     }
102                     try {
103                         Thread.sleep(2000);
104                     } catch (InterruptedException e) {
105                         //恢复中断
106                         Thread.currentThread().interrupt();
107                     }
108                     System.out.println(String.format("%s: 信号灯-%s 通行",Thread.currentThread().getName(),light.getLightColor()));
109                 }
110             });
111             threads.add(thread);
112             thread.start();
113         }
114 
115         //等待输入命令切换交通信号灯
116         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
117         String command;
118         while ((command = reader.readLine()) != null) {
119             if(command.equals("switchRed")) {
120                 light.switchRed();
121                 Thread.sleep(1000);
122                 System.out.println(String.format("等待线程数:%d",light.getQueuedThreads().size()));
123             } else if(command.equals("switchGreen")) {
124                 light.switchGreen();
125                 Thread.sleep(500);
126                 System.out.println(String.format("等待线程数:%d",light.getQueuedThreads().size()));
127             } else if (command.equals("stop")){
128                 System.out.println("terminating...");
129                 threads.forEach(Thread::interrupt);
130                 break;
131             }
132         }
133     }
134 }

 

然后是我自己实现的代码

 1 public class Demo4 {
 2 
 3     public static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
 4     public static Lock readLock = readWriteLock.readLock();
 5     public static Lock writeLock = readWriteLock.writeLock();
 6     public static void main(String[] args) throws IOException {
 7         writeLock.lock();
 8         try {
 9             new CartThread("汽车A").start();
10             new CartThread("汽车B").start();
11             new CartThread("汽车C").start();
12             System.out.println("请输入信号灯 red为红灯  green为绿灯");
13             BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
14             String command;
15             while ((command = reader.readLine()) != null) {
16                 if(command.equals("red")) {
17                     System.out.println("红灯亮  所有车停止通行");
18                     if(readWriteLock.getWriteHoldCount()==0)
19                     writeLock.lock();
20                 }else if(command.equals("green")){
21                     System.out.println("绿灯亮  所有车开始通行");
22                     writeLock.unlock();
23                 }
24             }
25         }finally {
26             writeLock.unlock();
27         }
28     }
29     static class CartThread extends Thread{
30         public CartThread(String name) {
31             super(name);
32         }
33         @Override
34         public void run() {
35             while ( true ){
36                 readLock.lock();
37                 System.out.println(Thread.currentThread().getName()+"  :绿灯--发车");
38                 try {
39                     Thread.sleep(2000);
40                 } catch (InterruptedException e) {
41                 }finally {
42                     readLock.unlock();
43                 }
44             }
45         }
46     }
47 }

 

以上均为个人的解决方案,如果有不对欢迎指正

posted @ 2019-03-05 16:50  雨落寒沙  阅读(422)  评论(0编辑  收藏  举报