public class JoinLockThreadOne extends Thread {
public void run(){
System.out.println(Thread.currentThread().getName() +" thread_one start: "+ new Date());
JoinLockThreadTwo two = new JoinLockThreadTwo();
two.start();
try {
two.join(2000);//线程2加入到线程1里, 线程2先执行。但是线程1只会等线程2 2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +" thread_one end: "+ new Date());
}
}
public class JoinLockThreadTwo extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + " thread_two start: "+ new Date());
JoinLockThreadThree three = new JoinLockThreadThree(this);
three.start();
try {
Thread.sleep(5000);//线程2 5秒
// three.join(5000);//线程3加入到线程2里, 线程3先执行。但是线程2只会等线程3 5秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " thread_two end: "+ new Date());
}
}
public class JoinLockThreadThree extends Thread{
private JoinLockThreadTwo two;
public JoinLockThreadThree(JoinLockThreadTwo two) {
this.two = two;
}
public void run(){
//在two执行过程中 one等待的过程中 three将two对象锁定
System.out.println(Thread.currentThread().getName() + " thread_three start: "+ new Date());
synchronized (two){
System.out.println(Thread.currentThread().getName() + " two is locked: "+ new Date());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " two is free: "+ new Date());
}
System.out.println(Thread.currentThread().getName() + " thread_three end: "+ new Date());
}
}
JoinLockThreadOne one = new JoinLockThreadOne();
one.start();
结果分析
执行 | 结果分析 | 分析 |
---|---|---|
Thread-0 thread___one start: Mon May 22 21:51:46 CST 2023 | 线程1 启动并执行, 线程2 启动并join 到 线程1 里 | |
Thread-1 thread___two start: Mon May 22 21:51:46 CST 2023 | 线程2 执行, 线程3 启动并执行, | |
Thread-2 thread_three start: Mon May 22 21:51:46 CST 2023 | 线程3 启动并执行 | |
Thread-2 two is locked: Mon May 22 21:51:46 CST 2023 | 线程3 获取到锁 two | 在2s之内都是线程3优先执行(线程1需要等2s,线程2休眠5s),执行代码锁定 two对象 10s。 过了2s之后,(线程2 sleep 5s )(线程3 sleep 10s), 故线程1执行, 线程1想把线程2从自己的线程内删除,但是发现two对象不在自己手里,而是被线程3锁定10s,线程1只能等待。 (5s以后线程2才会醒,还有3s,这3s就不清楚线程1一直在等待,还是循环获取到执行权然后被拒绝的这种循环???) |
Thread-1 thread___two end: Mon May 22 21:51:51 CST 2023 | 线程2 休眠 5 秒后,开始执行 | 5s 以后线程2醒了,( 线程3 sleep 10s ),故线程2和线程1争夺资源,线程1获得执行权也是被拒绝,线程2获取到执行权才会去执行 |
Thread-2 two is free: Mon May 22 21:51:56 CST 2023 | 线程3 休眠 10 秒后释放锁 two | (尽管过了2s 之后线程1想把线程2从自己的线程内删除,但是发现two对象不在自己手里,而是被 线程3锁定 10s , 线程1只能等待),即使线程1获得执行权也是被拒绝,,一直等到10s 后线程3将two对象释放 |
Thread-0 thread___one end: Mon May 22 21:51:56 CST 2023 | 线程1 只等 2 秒,早已超过,和 线程3 竞争 | 线程3将two对象释放后,此时线程1和线程3争夺资源,谁执行完全随机。 如果线程1获取到执行权的话,线程1把线程2从自己的线程内删除。 对于最后的输出语句,线程1和线程3争夺资源,最后这两步不一定谁先执行 |
Thread-2 thread_three end: Mon May 22 21:51:56 CST 2023 | 线程3 执行完毕 |
以上例子可以得到:
synchronized
锁非常的厉害, 一旦对象被锁定不释放的情况下,其他的对象都需要等待