源码解析

Thread源码解析

static static native 实例方法 sychronized实例方法
interrupted stop join
yield(可能转让使用权) interrupt
isInterrupted

img

sleep

public static native void sleep(long millis) throws InterruptedException;

Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.

有限等待,属于static、native方法,意味着所有线程实例实际都调用的这个方法

yield

img

    /**
     * A hint to the scheduler that the current thread is willing to yield
     * its current use of a processor. The scheduler is free to ignore this
     * hint.
     */
	public static native void yield();

让出CPU一点时间,属于static、native方法,所有线程实例都调用该方法,不一定会真的让出CPU。

join

img

	/**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     */
public final synchronized void join(long millis) throws InterruptedException {

interrupt方法

线程中断之前的版本有stop方法,但是已经被设置为过时。现在没有强制使线程终止的方法!

公共实例方法interrupt()

public void interrupt() {}

由于stop方法是线程A终止线程B的方法

  • 被终止的线程B可能立即释放锁,可能会让对象处于不一致的状态
  • 线程A也不知道线程B什么时候能被终止,线程B的某些操作可能被直接中断
if (threadStatus != 0) {
            resume(); // Wake up thread if it was suspended; no-op otherwise
        }

        // The VM can handle all thread states
        stop0(new ThreadDeath());

我们一般使用interrupt方法来中断线程

  • 要注意的是:interrupt方法不会真的中断线程,而是修改线程的标志位
  • 也就是说:Java线程设计者实际是想线程自己来终止,通过上面的信号,就可以判断该执行什么状态
  • 到底是中断还是继续运行,都是由线程自己决定

当你在线程上调用interrupt()时,线程中断发生的唯一时刻是在任务要进入到可中断的阻塞操作(如sleep,wait, join等)中,或者已经在阻塞操作内部时。此时线程会抛出InterruptedException,并从异常中退出。如果run()方法内部恰巧没有可以产生阻塞的部分,则run()方法可能就无法被interrupt方法中断。此时,可以调用interrupted()方法判断线程的终止状态,并根据状态控制线程的中断

class InterruptedClass implements Runnable {
    @Override
    public void run() {
        double d = 0.0f;
        try {
            while(!Thread.interrupted()) {
                System.out.println("Running in InterrupedClass");
                // before sleep, point 1
                Thread.sleep(2000);
                // before calculating, point 2
                System.out.println("Calculating...");
                for (int i = 0; i < 900000; i++) {
                    d = d + (Math.PI + Math.E) / d;
                }
                System.out.println("After calculating");
            }
        }catch(InterruptedException e) {
            System.out.println("Exiting via InterruptedException");
        }finally {
            System.out.println("In finally!");
        }
    }
}

public class Interrupt {

    public static void main(String[] args) throws Exception {
        ExecutorService exec = Executors.newCachedThreadPool();
        exec.execute(new InterruptedClass());

//        Thread.sleep(1000);  // 如果睡眠1000ms,则在point1处之前就调用了shutdownNow,即调用了interrupt
        // 因此再调用sleep方法时会抛出异常并从catch处退出
		
        Thread.sleep(2005);  // 如果睡眠2005ms,则在point2处调用interrupt,即在正常运行处调用interrupt
        // 因此会执行完循环中的大数计算,再词运行到while(!Thread.interrupted())处
        // 时才回中断,退出while,不抛出异常通过自己结束循环的方式退出
        // finally或catch中可以添加释放占用资源的代码
        exec.shutdownNow();
    }

}

interrupted方法

静态方法

public static boolean interrupted() {}

清除中断标志位,将其设为true

isInterrupted方法

实例方法

public boolean isInterrupted() {
        return isInterrupted(false);//ClearInterrupted == false
    }

不清除中断标志位,

posted @ 2019-03-13 18:06  随风而行-  阅读(284)  评论(0编辑  收藏  举报