并发基础
创建线程的三种方式
- extends Thread
- implements Runnable
- implements Callable
三种方式比较
- 继承实现:当前线程直接使用this,不需Thread.currentThread;Java只能单继承,任务与代码没有分离,没有返回值
- Runnable:多线程进行同一任务只需要一份代码;没有返回值
- 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()
- sleep()是Thread的方法而不是Object的方法
- 线程调用sleep()让出执行权(这里的执行权是啥意思。如果线程在使用cpu则让出,如果没有在使用cpu则不参与cpu调度?)不参与cpu调度
- 不会让出已拥有的监视器资源,比如监视器锁。
- 指定时间过后线程进入就绪状态,重新参与cpu的调度。
- 睡眠期间被调用该线程的interrupt()回报异常
sleep(-1)报错
让出cpu使用权 yield()
暗示线程调度器:本线程使用cpu的时间片剩余时间不想用了,分配时间片给其他线程。
线程调度器可以无视该暗示
本线程让出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); |
判断线程是否被中断,若线程被中断则消除中断标志
线程上下文切换
时机:
- 线程时间片使用完处于就绪状态
- 线程被其他线程中断