2019独角兽企业重金招聘Python工程师标准>>>
最近遇到一个有点意思的题目,要控制两句数据的顺序,其实就是控制主线程和子线程的执行顺序。
原代码如下
public class TestAB {
public static void A() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("2 " + System.currentTimeMillis());
}
}).start();
System.out.println("1 " + System.currentTimeMillis());
}
public static void main (String[] args) {
A();
}
}
正常情况下都会先输出1 再输出2
但是要求先输出2 再输出1 ,可以用线程通信来尝试解决。
可以用 锁、volatile、wait、join、interrupted 这五种方式
1、volatile
volatile的介绍之前有写过 volatile 介绍
修改后的代码如下,先创建一个volatile 的boolean值,初始值为false,在输出2之后再修改为true
do while 循环体只做循环其他的不执行,直到 isRun 被修改为true,再执行 if 语句。这是一种方式。
public class TestAB {
public volatile static boolean isRun = false;
public static void A() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("2 " + System.currentTimeMillis());
isRun = true;
}
}).start();
do {} while (!isRun);
if(isRun) {
System.out.println("1 " + System.currentTimeMillis());
}
}
public static void main (String[] args) {
A();
}
}
2、join
修改后代码如下,主线程调用子线程的 join 方法,主线程等子线程执行完再继续执行,此时也能实现先输出2再输出1
public class TestJoin {
public static void A() {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("2 " + System.currentTimeMillis());
}
});
t1.start();
try {
t1.join();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("1 " + System.currentTimeMillis());
}
public static void main (String[] args) {
A();
}
}
3、interrupted
修改后如下,原理与第一种方式相似,等输出2后再修改标志位,还没调用interrupted时,isInterrupted 返回false,调用后就会返回true,也可以做到控制主线程和子线程的执行顺序。
interrupted 介绍
public class TestInterrupted {
public static void A() {
final Thread main = Thread.currentThread();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("2 " + System.currentTimeMillis());
main.interrupt();
}
}).start();
do { } while(!main.isInterrupted());
if(main.isInterrupted()) {
System.out.println("1 " + System.currentTimeMillis());
}
}
public static void main (String[] args) {
A();
}
}
wait 和 锁的也类似,使用wait也得加锁。
“把start改成run也可以~ 那就不是多线程了哈哈~ 只是执行一个run方法,主线程按顺序执行”