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()作用于此线程,即代码中调用此方法的实例所代表的线程。