0%

Java并发

并发基础

创建线程的三种方式

  1. extends Thread
  2. implements Runnable
  3. implements Callable

三种方式比较

  1. 继承实现:当前线程直接使用this,不需Thread.currentThread;Java只能单继承,任务与代码没有分离,没有返回值
  2. Runnable:多线程进行同一任务只需要一份代码;没有返回值
  3. Callable:有返回值

总结:

使用继承方便传参,通过设置子类的私有属性,set方法,构造方法进行参数传递,Runnable只能使用主线程声明的final变量;但Java单继承,继承了Thread后无法继承其他类。继承和Runnable都没有返回值,Callable–FutureTask可以有返回值

线程唤醒与等待

为什么是用共享变量(锁对象)的wait()而不是线程对象的wait()?

为何这三个不是Thread类声明中的方法,而是Object类中声明的方法(当然由于Thread类继承了Object类,所以Thread也可以调用者三个方法)?其实这个问题很简单,由于每个对象都拥有monitor(即锁),所以让当前线程等待某个对象的锁,当然应该通过这个对象来操作了。而不是用当前线程来操作,因为当前线程可能会等待多个线程的锁,如果通过线程来操作,就非常复杂了。

=======================================================
上面已经提到,如果调用某个对象的wait()方法,当前线程必须拥有这个对象的monitor(即锁),因此调用wait()方法必须在同步块或者同步方法中进行(synchronized块或者synchronized方法)。如果当前线程没有这个对象的锁就调用wait()方法,则会抛出IllegalMonitorStateException.

=======================================================
调用某个对象的wait()方法,相当于让当前线程交出(释放)此对象的monitor,然后进入等待状态,等待后续再次获得此对象的锁(Thread类中的sleep方法使当前线程暂停执行一段时间,从而让其他线程有机会继续执行,但它并不释放对象锁);
————————————————
版权声明:本文为CSDN博主「Demon_HL」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Demon_HL/java/article/details/104984117

wait()、notify()、notifyAll()都是针对共享变量的等待与唤醒,一个共享变量可以被多个线程所等待,唤醒哪个变量是随机的。只有获取到共享变量的监视器锁的线程才可以继续运行

等待线程执行终止 join()

A线程调用B线程的join()方法,A线程阻塞等待B线程执行完毕,中途若其他线程调用A线程的interrupt()则报异常

线程睡眠 sleep()

  1. sleep()是Thread的方法而不是Object的方法
  2. 线程调用sleep()让出执行权(这里的执行权是啥意思。如果线程在使用cpu则让出,如果没有在使用cpu则不参与cpu调度?)不参与cpu调度
  3. 不会让出已拥有的监视器资源,比如监视器锁。
  4. 指定时间过后线程进入就绪状态,重新参与cpu的调度。
  5. 睡眠期间被调用该线程的interrupt()回报异常

sleep(-1)报错

让出cpu使用权 yield()

  1. 暗示线程调度器:本线程使用cpu的时间片剩余时间不想用了,分配时间片给其他线程。

  2. 线程调度器可以无视该暗示

  3. 本线程让出cpu后处于就绪状态,还参与cpu调度,线程调度器分配cpu给优先级最高的线程,下一个时间片可能还被分配给该线程

yield()与sleep()的区别:

yield让出cpu,但出于就绪状态,参与cpu下一轮调度

sleep让出cpu,在指定时间之前都处于阻塞状态,不参与cpu调度

线程中断

  • void interrupt()

调用线程的interrupt(),给线程的中断标志设置为true,但线程并不会被中断,而是继续执行。

若该线程调用了wait(),join(),sleep()被阻塞挂起时再调用interrupt()会报interruptedException异常

  • boolean isInterrupted()
1
return isInterrupted(false);

判断线程是否被中断,不改变线程中断状态

  • boolean interrupted()——–静态方法
1
return currenrThread.isInterrupted(true);

判断线程是否被中断,若线程被中断则消除中断标志

线程上下文切换

时机:

  1. 线程时间片使用完处于就绪状态
  2. 线程被其他线程中断

线程死锁

Donate comment here.

欢迎关注我的其它发布渠道