线程先后执行问题
多个线程按顺序执行进行字符串拼接问题
记录一下这两天笔试遇到的一个笔试题。
问题描述:
从键盘输入一个字符串,在程序中创建三个线程,要求这三个线程先后执行,向字符串后拼接 “_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
吾生也有涯,而知也无涯。