【JAVA基础--多线程中常用的方法】

线程中的静态方法

1. sleep()方法:不释放锁

概念:sleep会使当前线程睡眠指定时间(就是说当前线程暂停一段时间让给别的线程去运行,等到睡眠时间结束,线程自动复活),不释放锁

关于释放锁 / 不释放锁
sleep()是不释放锁的;也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象;因为当前线程仍然持有该对象的锁。

用法

public class ThreadTest extends Thread {
    @Override
    public void run() {
        System.out.println("我是重写后的run方法");
        try {
            sleep(2000);//ms单位
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("我是睡眠后被执行的");
    }

    public static void main(String[] args) {
        ThreadTest t1=new ThreadTest();
//        ThreadTest t2=new ThreadTest();
        t1.start();
    }
}

线程状态:调用sleep方法使得线程从运行态—>阻塞态

2. yield()方法:不释放锁

概念: yield暂停当前正在执行的线程对象,让cpu去执行其他具有相同优先级的线程,不释放锁

1.是让当前线程交出CPU权限,让CPU去执行其他具有相同优先级的的线程;
2.使得线程回到就绪态,以允许具有相同优先级的其他线程获得运行机会。
3.使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

总结: yield方法只能让拥有优先级的线程获取CPU执行时间的机会,调用该方法不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行的时间。
线程状态:调用yield方法使得线程从运行态—>就绪态
用法: 同上

但是yield不能立刻交出CPU,会出现同一个线程一直执行的情况,另外,yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会。

举例:

public class ThreadTest extends Thread {
    public void run() {
        System.out.println("In run");
        yield();
        System.out.println("Leaving run");
    }
    public static void main(String []argv) {
        (new ThreadTest()).start();
    }
}
//答案:程序运行可能输出先有In run后有Leaving run

线程中的实例方法

1. start()方法

我们去调用,想让线程去执行的方法

线程创建以后,并不会自动运行,需要我们手动的调用start把线程的状置为为就绪状态;但不一定马上就被运行,得等到CPU分配时间片以后,才会运行。
线程状态:调用start()方法,创建—>就绪

2. run()方法

cpu去调用,线程被真正 执行的方法

线程真正要执行的逻辑,当一个线程被分配到cpu资源,开始启动就会调用run方法执行

线程状态就绪—>运行

3. join()方法:释放锁

概念:join方法,当前线程调用某线程.join()时会使当前线程等待某线程执行完毕再结束,底层调用了wait,释放锁

t1和t2两个线程,如果在t1线程里面调用了t2.join(),则t1线程会进行等待状态,t2运行结束以后,才会继续运行t1。这样可以保证线程的先后顺序。

线程状态:调用join()方法,线程从运行态—>阻塞态

4. wait()方法:释放锁 【wait notify notifyAll本质上是Object类的方法】

注意:wait() 其实是Object类里面的方法,调用对象的wait方法导致线程放弃CPU的执行权,同时也放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool)

概念wait()使当前线程阻塞,使当前线程回到线程池中等待,释放锁,当被其他线程使用notify,notifyAll 唤醒时进入就绪状态;(前提是必须先获得锁)

一般配合synchronized来使用,即:在 synchronized 同步代码块里使用 wait()、notify() / notifyAll() 方法wait方法由当前所有的local对象里面调用,this.wait(),必须被try catch包围,保证即使异常中断也可以使wait等待的线程唤醒。执行了wait方法,需要被别的线程通过同一个对象的notify方法唤醒。

线程状态:调用wait()方法,线程从运行态—>阻塞态
总结wait notify notifyAll都必须在持有有锁的代码中

5. notify() / notifyAll()方法:释放锁(不是立刻释放)

概念

  • obj.notify:随机唤醒对象obj的某个wait线程,使被唤醒的线程进入就绪状态。

  • obj.notifyAll:唤醒对象obj的所有wait线程,使被唤醒的线程进入就绪状态。

总结

  • notify/notifyAll()的执行只是唤醒沉睡的线程,而不会立即释放锁,锁的释放要看代码块的具体执行情况。
  • notify后不会立刻唤醒线程,而是等notify所在的synchronized(obj){}代码块执行完了,才会唤醒wait线程。
  • 在编程中,我们在使用notify/notifyAll() 后尽量迅速退出临界区,以唤醒其他线程让其获得锁。

总结:

  1. sleep会使当前线程睡眠指定时间,不释放锁;
  2. join()底层就是调用wait()方法的,wait()释放锁资源,故join也释放锁资源
  3. yield会使当前线程重回到就绪状态,等待cpu的调度,不释放锁
  4. wait会使当前线程回到线程池中等待,释放锁,当被其他线程使用notify,notifyAll唤醒时进入可执行状态(就绪态)
  5. 当前线程调用 某线程 .join()时会使当前线程等待某线程执行完毕再结束,底层调用了wait,释放锁
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大龄烤红薯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值