• 线程先后执行问题


    多个线程按顺序执行进行字符串拼接问题

    记录一下这两天笔试遇到的一个笔试题。

    问题描述:

      从键盘输入一个字符串,在程序中创建三个线程,要求这三个线程先后执行,向字符串后拼接 “_A" 、”_B“、”_C“,最后打印输出结果。

     

    例:

      输入:czc

      输出:czc_A_B_C

    分析一下这道题的主要考点,主要还是对于线程知识的考核,线程之间信息共享以及多线程的管理问题。

    这里我感觉解题方法还是挺多的,利用线程池、加锁的方式都可以解决,设置线程优先级应该也能解决这个问题。

    这里面线程池应该算是最简单的方式了,毕竟不需要自己动手做线程管理,当时我写的时候用的线程池写的,但是时间超限制了,想偷懒结果最后没成功。

    下面是一些代码实现,以后有空再回来补充。

    补充一个方法(2019/9/4)

     这两天看博客碰到一个新的方法可以解决这个问题,参考了这篇博客:https://blog.csdn.net/u010185035/article/details/81172767,特此感谢。

    这里就利用线程的 join() 方法来解决这里这个问题,见下面的第三个方法。

    1、线程池

    import java.util.Scanner;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class Main {
        static String str;
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            str = cin.next();
            final Thread MyThread1=new Thread(new Runnable(){
                @Override
                public void run() {
                    str=str+"_"+"A";
                }
            });
    
            final Thread MyThread2=new Thread(new Runnable(){
                @Override
                public void run() {
                    str=str+"_"+"B";
                }
            });
            final Thread MyThread3=new Thread(new Runnable(){
                @Override
                public void run() {
                    str=str+"_"+"C";
                    System.out.println(str);
                }
            });
            ExecutorService executor = Executors.newSingleThreadExecutor();
            executor.submit(MyThread1);
            executor.submit(MyThread2);
            executor.submit(MyThread3);
            executor.shutdown();
        }
    }

    2、加锁

    import java.util.Scanner;
    public class Ping {
        static String str;
        static int i=0;
        static String[] s={"_A","_B","_C"};
        public static void main(String[] args){
            Scanner scanner=new Scanner(System.in);
            str=scanner.next();
            new Thread(new MyThread()).start();
            new Thread(new MyThread()).start();
            new Thread(new MyThread()).start();
        }
        static class MyThread implements Runnable{
            @Override
            public void run(){
              synchronized(Ping.class){
                  str=str+s[i];
                  i++;
                  if(i==3){
                      System.out.println(str);
                  }
              }
            }
        }
    }

    贴一下运行结果截图:

    3、利用 join()方法

    import java.util.Scanner;
    public class TestJoin {
        static String string="";
        static Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                string=string+"_A";
            }
        });
        static Thread t2=new Thread(new Runnable() {
            @Override
            public void run() {
                string=string+"_B";
            }
        });
        static Thread t3=new Thread(new Runnable() {
            @Override
            public void run() {
                string=string+"_C";
            }
        });
    
        public static void main(String[] args) throws InterruptedException {
            Scanner scanner=new Scanner(System.in);
            string=scanner.next();
    
            long time1=System.currentTimeMillis();
            t1.start();
            t1.join();
            t2.start();
            t2.join();
            t3.start();
            t3.join();
            System.out.println(string);
            long time2=System.currentTimeMillis();
            System.out.println(time2-time1);
        }
    }

    一些个人见解

    显然线程池的方式是最符合题意的,三个线程顺序执行,就是时间超限制了,这里就没办法了。

    用加锁的方式虽然看上去是顺序执行进行拼接,但实际上这三个线程之间的先后顺序并不确定,这里如果给线程编号并打印就会露出狐狸尾巴了。

    以后有解决方案再回来补充。

    补充第三个方法的见解:

    这里利用的 join() 方法也是一个很好的思路,参考了网上的博客。

    这里主要就是在启动了子线程 t1 后,就阻塞了主线程,所以后面的 t2.start(),t3.start() 方法没有得到执行,也就得到了我们想要的效果。

    这里测试显示的这个方法所耗的时间很短,显然会更好一些。

     更新时间:2019/9/4

    吾生也有涯,而知也无涯。

  • 相关阅读:
    RvmTranslator7.3.2
    PipeCAD
    Open CASCADE Technology 7.5.0 released
    IsoAlgo 环路处理
    OD流向地图的绘制——利用ArcGIS与Gephi方法
    Python调用百度地图和高德地图API批量获取国内城市地址经纬度坐标
    ArcGIS地理数据库Geodatabase
    Gephi 安装与简明教程
    安装Java SDK
    ArcGIS中自定义脚本工具制作
  • 原文地址:https://www.cnblogs.com/hzauxx/p/11433146.html
Copyright © 2020-2023  润新知