线程先后执行问题

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

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

问题描述:

  从键盘输入一个字符串,在程序中创建三个线程,要求这三个线程先后执行,向字符串后拼接 “_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

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

原文地址:https://www.cnblogs.com/hzauxx/p/11433146.html