join();—->Thread类
让多个线程同步执行 变成单个线程
join()方法底层其实是调用了wait()方法
1.有两个线程 one two two加到one里
2.设计模型的时候 将two线程在one的run方法里创建 保证两个有先后顺序
3.two.join();无参数 —-> join(0); 有参数 —-> join(long millis);—->
if (millis == 0) {//即 join(0);
while (isAlive()) { //没人调用方法就相当于this.isAlive() 即two对象调 如果two活着
wait(0); //this.wait(0)—->让别人等着 即访问two对象的线程进入等待状态 即one
}
}
4. one对象只有两个时间点访问到two对象
1 two想要join的时候
2 two执行完毕 或 join(millis)中等待的时间到的时候
线程one:
public class ThreadOne extends Thread{public void run(){System.out.println("ThreadOne 执行了");ThreadTwo two = new ThreadTwo();two.start();try {two.join(2000);//线程2加到线程1中//join();不带参数的相当于调的是join(long); 即join(0);//join(2000)即表明one给two的执行时间 若执行比我们的时间长 one会把two踢走 自己继续执行} catch (InterruptedException e) {e.printStackTrace();}System.out.println("ThreadOne 结束了");}}
线程two:
public class ThreadTwo extends Thread{public void run(){System.out.println("two 执行了");ThreadThree three = new ThreadThree(this);//this就是当前调用run方法的那个two对象//传进去的two对象就能保证three的run方法锁的是这个two对象three.start();try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("two 结束了");}}
线程three:
public class ThreadThree extends Thread{//这里是为了能在run方法中把join到one里执行的那个two对象锁起来//但是又不能在run方法里new一个two对象 这样就不是同一个two对象了//而且run方法是重写的 不能传参//所以只能加属性private ThreadTwo two;//调用three的构造方法时 two就有了public ThreadThree(ThreadTwo two){this.two = two;}public void run(){System.out.println("three 执行了");//在two执行的过程中 one等待时 three把two对象锁起来synchronized (two) {//把线程2锁住了//即one对象想把two对象踢走时 发现two对象被锁定了 那么one对象只能等待three把two释放System.out.println("two 被锁了");try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("two自由了");}System.out.println("three 执行完毕");}}
主方法:
public static void main(String[] args){ThreadOne one = new ThreadOne();one.start();}
