Java线程部分join(long)跟sleep(long)的区别

  • 首先看一下方法join(long)的内部是怎么实现的:源码: 可以看出:内部是调用wait方法来实现的,而wait方法具有释放锁的特点,从源码可以看出执行wait方法之后,当前线程的锁被释放,那么其他线程就可以 调用此线程中的同步方法了
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");
    }
    if (millis == 0) {
        while (isAlive()) {
            wait(0);
        }
    } else {
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);//注意此处,内部是调用wait方法来实现的;
            now = System.currentTimeMillis() - base;
        }
    }
}
  • 看一下sleep源码:是个本地的静态方法,由前面的学习我们知道sleep方法执行完是不能释放锁的,当sleep所在的方法内部的代码执行完了之后才会释放锁
public static native void sleep(long millis) throws InterruptedException;
  • 实验验证sleep方法不释放锁:
/**
* 演示sleep方法具有不释放锁的特点;
*
*/
class Thread5A extends Thread{
    private Thread5B thread5B;
    public Thread5A(Thread5B thread5B) {
        this.thread5B = thread5B;
    }
    @Override
    public void run() {
        try{
            synchronized (thread5B){
                thread5B.start();
                Thread.sleep(6000);
                System.out.println("sleep不释放锁------");
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
class Thread5B extends Thread{
    @Override
    public void run() {
        try {
            System.out.println("B线程的开始"+System.currentTimeMillis());
            Thread.sleep(3000);
            System.out.println("B线程的结束"+System.currentTimeMillis());
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
    synchronized public void bService(){
        System.out.println("调用一下B线程里的另外一个同步方法;"+System.currentTimeMillis());
    }
}
class Thread5C extends Thread{
    private Thread5B thread5B;
    public Thread5C(Thread5B thread5B) {
        this.thread5B = thread5B;
    }
    @Override
    public void run() {
        thread5B.bService();
    }
}
public class Test5 {
    public static void main(String[] args) throws InterruptedException {
        Thread5B b = new Thread5B();
        Thread5A a = new Thread5A(b);
        a.start();
        Thread.sleep(1000);
        Thread5C c = new Thread5C(b);
        c.start();
    }
}

/*
   运行结果:


  B线程的开始1558623812333
            B线程的结束1558623815333
sleep不释放锁------
        调用一下B线程里的另外一个同步方法;1558623818324
       注意最后C线程调用B线程另一个同步方法的时间,
       一直从B线程开始执行等了6秒,
       可是B线程3秒已经执行完了;
       这是因为A线程持有B线程类对象的锁6秒
       所以只有在A线程6秒结束释放B对象的锁的时候
       才能调用ThreadB中的另外一个同步方法;
       此实验证明sleep方法不释放锁;
        */

运行结果:
在这里插入图片描述

  • 下面验证一下join()方法释放锁的特点
/**
 * 验证join方法释放锁的特点
 */
class Thread6A extends Thread{
    private Thread6B thread6B;

    public Thread6A(Thread6B thread6B) {
        this.thread6B = thread6B;
    }
    @Override
    public void run() {
        try{
            synchronized (thread6B){
                thread6B.start();
                thread6B.join(4000);
                System.out.println("sleep不释放锁------");
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
class Thread6B extends Thread{
    @Override
    public void run() {
        try {
            System.out.println("B线程的开始"+System.currentTimeMillis()+"----");
            Thread.sleep(3000);
            System.out.println("B线程的结束"+System.currentTimeMillis()+"----");
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
    synchronized public void bService(){
        System.out.println("调用一下B线程里的另外一个同步方法;"+System.currentTimeMillis());
    }
}

class Thread6C extends Thread{
    private Thread6B thread6B;

    public Thread6C(Thread6B thread6B) {
        this.thread6B = thread6B;
    }
    @Override
    public void run() {
        thread6B.bService();
    }
}
public class Test6{
    public static void main(String[] args) throws InterruptedException {
        Thread6B b = new Thread6B();
        Thread6A a = new Thread6A(b);
        a.start();
        Thread.sleep(1000);
        Thread6C c = new Thread6C(b);
        c.start();
    }
}
/*
    运行结果:
		    B线程的开始1558787599534----
		    调用一下B线程里的另外一个同步方法;1558787600533
		    sleep不释放锁------
            B线程的结束1558787602534----
            实验多次证明,一旦在A线程里面B线程启动后调用了join(long)方法,
            就会立即(几乎是立即)交出锁,
   */

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值