• 遇到的一些多线程案例(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 }

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

  • 相关阅读:
    cc.Component
    cc.Node—坐标系统
    cc.Node—事件响应
    cc.Node—Action
    cc.Node—场景树
    console.log格式化及console对象
    网站开发学习Python实现-Django项目部署-介绍(6.2.1)
    个人博客搭建Python实现-尝试-遇到的问题(10.1.1)
    工具-Redis-django存储session(99.6.4)
    工具-Redis-与Python一起使用(99.6.3)
  • 原文地址:https://www.cnblogs.com/hetutu-5238/p/10477875.html
Copyright © 2020-2023  润新知