Java多线程学习:Join()

方法join的作用是使所属的线程对象x正常执行run()方法中的任务,而使当前线程Z进行无限期的阻塞,等待线程X销毁后再继续执行线程Z后面的代码。一般用于子线程先执行完毕再继续执行主线程的情况。

但是join方法后面的代码会不会提前执行呢?看下面的代码

 1 public class ThreadA extends Thread {
 2
 3     private ThreadB threadB;
 4
 5     public ThreadA(ThreadB threadB) {
 6         super();
 7         this.threadB = threadB;
 8     }
 9
10     @Override
11     public void run() {
12         synchronized (threadB) {
13             System.out.println("begin A ThreadName=" + Thread.currentThread().getName());
14             try {
15                 Thread.sleep(5000);
16             } catch (InterruptedException e) {
17                 e.printStackTrace();
18             }
19             System.out.println("end A ThreadName=" + Thread.currentThread().getName());
20         }
21     }
22
23
24 }

 1 public class ThreadB extends Thread{
 2     @Override
 3     public void run() {
 4         System.out.println("begin B ThreadName=" + Thread.currentThread().getName());
 5         try {
 6             Thread.sleep(5000);
 7         } catch (InterruptedException e) {
 8             e.printStackTrace();
 9         }
10         System.out.println("end B ThreadName=" + Thread.currentThread().getName());
11     }
12 }

 1 public class Run {
 2     public static void main(String[] args) throws InterruptedException {
 3         ThreadB threadB = new ThreadB();
 4         ThreadA threadA = new ThreadA(threadB);
 5         threadA.start();
 6         threadB.start();
 7         threadB.join(2000);
 8         System.out.println("main thread");
 9
10     }
11 }

运行几次后会发现,大部分时候结果是

但也会出现如下结果

join方法后面的代码提前执行了,这是怎么一回事呢?我们修改Run.java,将join方法注释掉,再次运行,发现结果如下

通过多次运行Run.java文件后,可以发现一个规侓:main end往往都是第一个打印的。所以可以完全确定地得出一个结论:方法join(2000)大部分是先运行的,也就是先抢到ThreadB的锁,然后快速进行释放。

代码运行步骤如下:

1)b.join(2000)方法先抢到B锁,然后将B锁进行释放;

2)ThreadA抢到锁,打印 ThreadA begin 并且 sleep(5000);

3)ThreadA 打印 ThreadA end,并释放锁;

4)这时join(2000)和ThreadB争抢锁,而join(2000)再次抢到锁,发现时间已过,释放锁;

5)ThreadB 抢到锁打印 ThreadB begin,main线程也异步打印main end;

6)5秒之后再打印ThreadB end。

这样就会出现join方法后面的代码提前执行的情况。

原文地址:https://www.cnblogs.com/le-le/p/12074712.html

时间: 2024-09-30 06:32:16

Java多线程学习:Join()的相关文章

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程

Java多线程学习

写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢?如果你觉得此文很简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线

Java多线程学习(吐血超具体总结)

林炳文Evankaka原创作品. 转载请注明出处http://blog.csdn.net/evankaka 写在前面的话:此文仅仅能说是java多线程的一个入门.事实上Java里头线程全然能够写一本书了,可是假设最基本的你都学掌握好,又怎么能更上一个台阶呢?假设你认为此文非常简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 文件夹(?)[-] 一扩展ja

Java多线程学习(吐血超详细总结)转

目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1

java多线程学习--java.util.concurrent

CountDownLatch,api 文档:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. 假设我们要打印1-100,最

黑马程序员之Java多线程学习

android培训  java培训 期待与您交流! 这一篇文章主要关于java多线程,主要还是以例子来驱动的.因为讲解多线程的书籍和文章已经很多了,所以我也不好意思多说,呵呵.大家可以去参考一些那些书籍.我这个文章主要关于实际的一些问题.同时也算是我以后复习的资料吧,.呵呵大家多多指教. 同时希望多结交一些技术上的朋友.谢谢. -------------------------------------------------------------------------------------

[转]Java多线程学习(总结很详细!!!)

Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的线程函数用法.概述等.首先让我们来了解下在操作系统中进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据空间,

java多线程学习(3)

1)竞争条件 在实际的多线程应用中,通常会有两个或多个线程需要对共同的对象进行共享访问,如果两个线程访问相同的对象,而且每一个都调用了一个会改变对象状态的方法, 那么,线程就会相互倾轧.根据各个线程访问数据的不同顺序,可能会产生腐蚀现象.这种情况通常称为竞争条件. 2)同步 为了多个线程对共享数据的腐蚀,就需要对数据的存取实现同步:常用的同步方法有3种: 1.Reenlock 用Reenlock保护代码块的基本机构如下: 1 Lock myLock=new ReenLock; 2 3 myLoc

java多线程学习(2)

1)Callable和Future Runnable封装一个异步运行的任务:可以当成一个没有任何参数和返回值的异步方法,Callable和 Runnable类似,但是它有返回值和参数. Callable接口是一个参数化的类型,只有一个方法call. 1 public interface Callable<V> 2 3 { 4 5 V call()throws Exception; 6 7 } 类型参数v是指返回值的类型,例如Callable<Integer>代表最终返回一个Inte