在多线程环境下很难保证结果的一致性,多线程带来的好处就是并行处理提升效率,弊端就是出现了问题很难定位,可以看个例子就明白了,请将下面的代码拷到本地去执行,就会发现每次执行的结果不一样。
代码1
public class JoinDemo {
public static void main(String[] args) {
Thread thread1 = new Thread(()->{
System.out.println("1");
});
Thread thread2 = new Thread(()->{
System.out.println("2");
});
Thread thread3 = new Thread(()->{
System.out.println("3");
});
thread1.start();
thread2.start();
thread3.start();
}
}
怎么样才能每次结果都是123,那么就需要使用join。看下面的代码
代码2
public class JoinDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(()->{
System.out.println("1");
});
Thread thread2 = new Thread(()->{
System.out.println("2");
});
Thread thread3 = new Thread(()->{
System.out.println("3");
});
thread1.start();
thread1.join();
thread2.start();
thread2.join();
thread3.start();
}
}
为什么现在无论程序执行多少次,结果都是123,那就需要去看看join的源码到底做了什么如此神奇。
代码3
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
// 传入的就是0
if (millis == 0) {
while (isAlive()) {
// 等待0秒,起到阻塞的作用
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
}
好,那我们是否能自己写代码实现join方法类似的功能呢?当然可以,对代码2进行稍微的修改就可以了。
thread1.start();
Thread.sleep(3);
thread2.start();
Thread.sleep(3);
thread3.start();
多线程还有很多技术能控制线程的执行和阻塞,通过阻塞实现一些意向不到的效果,后续再分享。