sleep和wait方法区别
- 本质区别:sleep() 是 Thread 类的静态本地方法;wait() 是Object类的成员本地方法
- sleep() 方法可以在任何地方使用;wait() 方法则只能在同步方法或同步代码块中使用(也就是说当前线程必须持有当前对象的锁),否则抛出IllegalMonitorStateException
- sleep() 会休眠当前线程指定时间,释放 CPU 资源,
不释放对象锁
,休眠时间到自动苏醒继续执行。**wait() 方法会放弃持有的对象锁**
,进入等待队列,当该对象被调用 notify() / notifyAll() 方法后才有机会竞争获取对象锁,进入运行状态;而wait(long timeout)时间一到,无需其他线程唤醒,也会重新竞争获取对象的锁继续执行。 - 使用场景的区别:sleep 一般用于当前线程休眠,或者轮循暂停操作;wait 则多用于多线程之间的通信。
yield和join方法区别
yield()
它是Thread的静态本地方法。
作用:向调度器表明当前线程可以将执行权出让给其他优先级相同的线程,但调度器可以忽略这个建议,没有任何机制保证一定会出让执行权。
join()
这是Thread类的成员方法。
注释翻译:(调用这个方法的线程)等待当前线程直到销毁。
作用:让调用这个方法的线程等待这个Thread对象对应的线程直到它执行完毕。
注意:“主线程”一定要在这个Thread调用start()开启“子线程”后再调用它的join()才有效。
实现:join()会调用下面这个构造方法,其中会调用wait方法阻塞调用join方法的线程
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); //调用wait方法阻塞调用join方法的线程
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
两者的区别就在于两者的作用。
停止线程的几种方法
Thread.stop()
Thread的stop方法用来强行停止当前线程的执行,已被废弃。
stop方法的问题
- 调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作,无论是否在 catch 或 finally 语句中,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭。
- 调用 stop() 方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题。
Thread.interrupt()
Thread的interrupt方法的作用是给线程设置中断标志,并不会直接停止当前线程的执行。当当前线程被Object的wait方法、Thread的join、sleep等方法阻塞时调用interrupt方法时,此线程会收到一个InterruptedException并清除它的中断标志。
interrupt方法可以和return关键字结合来停止线程的执行。
public class interrupt {
public static void main(String[] args){
MyThread mythread = new MyThread();
mythread.start();
try{
Thread.sleep(10000);
}catch(InterruptedException e){
}
mythread.interrupt();
//mythread.flag=false;
}
}
class MyThread extends Thread{
public boolean flag =true;
public void run() {
while(true) {
System.out.println(new Date());
try {
sleep(1000);
} catch (InterruptedException e){
System.out.println("Oh,no!!");
return; //当前睡眠状态线程的interrupt方法被调用时,会进入这里处理异常
}
}
}
}
- 使用一个标记位停止线程
public class interrupt {
public static void main(String[] args){
MyThread mythread =new MyThread();
mythread.start();
try{
Thread.sleep(10000);
}catch(InterruptedException e){
}
mythread.flag = false; //停止线程只需要将标记位置为false
}
}
class MyThread extends Thread{
public boolean flag =true;
public void run(){
while(flag){
System.out.println(new Date());
try{
sleep(1000);
}catch(InterruptedException e){
System.out.println("Oh,no!!");
return;
}
}
}
}
Thread类中interrupt、interrupted和isInterrupted方法
- interrupt()是给线程设置中断标志;interrupted()是检测中断并清除中断状态;isInterrupted()只检测中断。
- interrupted()作用于当前线程,interrupt()和isInterrupted()作用于此线程,即代码中调用此方法的实例所代表的线程。