https://blog.csdn.net/qxs965266509/article/details/8134334
1 sleep(long millis):Thread类,必须带一个时间参数
-
sleep(long):
使调用该方法的线程进入停滞状态
,所以执行sleep()的线程在指定的时间内肯定不会被执行
; -
sleep(long)是
不会释放锁标志的
,也就是说如果有synchronized同步块,其他线程仍然不能访问共享数据
-
sleep(long)可使
优先级低的线程得到执行的机会
,当然也可以让同优先级的线程有执行的机会
-
该方法要捕捉异常
-
用途:例如有两个线程同时执行(没有synchronized)一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY。
如果没有Sleep()方法,只有高优先级的线程执行完毕后,低优先级的线程才能够执行
;但是高优先级的线程sleep(500)后,低优先级就有机会执行了
总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。
2 join():Thread类
Thread类中的join()的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行
。
- 用途:join()方法使调用该方法的线程在此之前执行完毕,也就是等待 该方法的线程执行完毕后 再往下继续执行
- 该方法
要捕捉异常
join()详情请看:
https://mp.csdn.net/mdeditor/81226972#
3 yield():Thread类,没有参数
-
sleep 方法使当前运行中的线程睡眠一段时间,
进入不可以运行状态
,这段时间的长短是由程序设定的
,yield方法使当前线程让出CPU占有权,但让出的时间是不可设定的
。 -
只能让同优先级 或 更高优先级的线程有执行的机会
-
yield()
不会释放锁标志
-
先检测当前
是否有 相同优先级 或 更高优先级 的线程处于同可运行状态
:
yield()详情请看:
https://blog.csdn.net/csdnlijingran/article/details/82974515
4 wait()、notify()、notifyAll():java.lang.Object
详情请看:
https://blog.csdn.net/csdnlijingran/article/details/88560966
这三个方法都是java.lang.Object
的方法。 协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用
。synchronized关键字用于保护共享数据,阻止其他线程对共享数据的存取,但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出synchronized数据块时让其他线程也有机会访问共享数据呢? 这三个方法的作用:此时就用这三个方法来灵活控制。
当线程执行wait()方法时候,会释放当前的锁
,然后让出CPU
,进入等待状态
。
只有当 notify/notifyAll() 被执行时候,才会唤醒一个或多个正处于等待状态的线程,然后继续往下执行,直到执行完synchronized 代码块的代码或是中途遇到wait() ,再次释放锁。
wait()方法
使当前线程暂停执行并释放对象锁标示,让其他线程可以进入synchronized数据块,当前线程被放入对象等待池
中。
当调用notify()方法
后,将从对象的等待池
中移走一个任意的线程并 放到 锁标志等待池
中,只有 锁标志等待池 中线程能够获取锁标志
;如果锁标志等待池中没有线程,则notify()不起作用
。
notifyAll()
则从对象等待池
中移走 所有等待那个对象的线程
并放到锁标志等待池
中。
常用的wait方法有wait()和wait(long timeout)
void wait() :在其他线程调用此对象的 notify() 方法或者 notifyAll()方法前
,导致当前线程等待
。
void wait(long timeout):在其他线程调用此对象的notify() 方法 或者 notifyAll()方法,或者超过指定的时间量前
,导致当前线程等待。
wait()后,线程会释放掉它所占有的“锁标志”
,从而使其他 想要锁住共享对象 的线程使用。
wait()和notify()因为会对对象的“锁标志”进行操作,所以他们必需在Synchronized函数或者 synchronized block 中进行调用
。如果在non-synchronized 函数或 non-synchronized block 中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常
。
5 interrupt()
https://blog.csdn.net/hudashi/article/details/6958550
interrupt()只是改变中断状态而已
。interrupt()不会中断一个正在运行的线程
。这一方法实际上完成的是,给受阻塞的线程抛出一个中断信号,这样受阻线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep
三种方法之一阻塞, 这时调用了该线程的interrupt(),那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态
。
如果线程没有被阻塞,这时调用interrupt()将不起作用
;否则,线程就将得到InterruptedException异常
(该线程必须事先预备好处理此状况),接着逃离阻塞状态。
-
线程A在
执行sleep,wait,join时
,线程B调用线程A的interrupt方法,的确这一个时候A会有InterruptedException 异常抛出来
。但这其实是在sleep,wait,join这些方法内部会不断检查中断状态的值
,而自己抛出的InterruptedException
。 -
如果线程A正在执行一些指定的操作时如赋值,for,while,if,调用方法等,
都不会去检查中断状态
,所以线程A不会抛出 InterruptedException,而会一直执行着自己的操作
。
注意
:当线程A执行到wait(),sleep(),join()时,抛出InterruptedException后,中断状态已经被系统复位了
,线程A调用Thread.interrupted()返回的是false
。
- sleep() & interrupt()
线程A正在使用sleep()暂停着: Thread.sleep(100000);
如果要取消他的等待状态,可以在正在执行的线程里(比如这里是B)调用
a.interrupt();
令线程A放弃睡眠操作,这里a是线程A对应到的Thread实例
当在sleep中时 线程被调用interrupt()时
,就马上会放弃暂停的状态.并抛出InterruptedException.丢出异常的,是A线程. - wait() & interrupt()
线程A调用了wait()进入了等待状态,也可以用interrupt()取消.
不过这时候要小心锁定的问题
.线程在进入等待区,会把锁定解除
,当等待中的线程调用interrupt()时
,会先重新获取锁定
,再抛出异常
.在获取锁定之前,是无法抛出异常的. - join() & interrupt()
当线程以join()等待其他线程结束时,当它被调用interrupt(),它与sleep()时一样, 会马上跳到catch块里。注意,是对谁调用interrupt()方法,一定是调用被阻塞线程的interrupt方法。
例如:在线程a中调用来线程t.join()
。则a会等t执行完后,在执行t.join后的代码,当在线程b中调用来 a.interrupt()方法
,则会抛出InterruptedException,当然join()也就被取消了
。
6 run和start()
把需要处理的代码放到run()方法中,start()方法启动线程将自动调用run()方法
,这个由java的内存机制规定的。并且run()方法必需是public访问权限,返回值类型为void
。
7 关键字synchronized
该关键字用于保护共享数据
,当然前提条件是要分清哪些数据是共享数据。每个对象都有一个锁标志
,当一个线程访问到该对象,被Synchronized修饰的数据将被"上锁"
,阻止其他线程访问。当前线程访问完这部分数据后,释放锁标志,其他线程就可以访问了
。