美文网首页
【多线程】重要的方法

【多线程】重要的方法

作者: 良辰夜 | 来源:发表于2018-05-16 00:54 被阅读0次

    想到哪,写到哪,后期再整理

    1.获取当前线程

    Thread.currentThread()

    2.线程阻塞相关方法(除开锁)

    2.1 sleep

    a) 方法一览

    public static native void sleep(long millis) throws InterruptedException;
    
    public static void sleep(long millis, int nanos)
        throws InterruptedException {
           //some method
            sleep(millis);
        }
    

    b) 问题

    1. 我们代码中写入Thread.sleep(200),在200ms后会立刻苏醒吗?
      答:Thread.sleep会让线程立刻从runnable到block,但是从block到runnable,需要等待被调度!

    join

    join有三个重载方法,最后都是调 join(long millis)
    所谓的join,可以本质是调用 currentThread().wait(millis);

    注意经典模式 Thread.currentThread().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);
                }
            } else {
                while (isAlive()) {//可能被唤醒
                    long delay = millis - now;
                    if (delay <= 0) {
                        break;
                    }
                    wait(delay);
                    now = System.currentTimeMillis() - base;
                }
            }
        }
    

    3 线程的停止

    3.1 flag停止法

    3.1.1 interrupt模式

    a)方法一览

    interrupt仅仅只是一个标记,不能直接打断线程

    //true就会打断线程,并返回是否被线程状态,
    //false则仅仅返回线程是否被打断
    private native boolean isInterrupted(boolean ClearInterrupted);
    
    //打断当前线程
    public static boolean interrupted() {
            return currentThread().isInterrupted(true);
    }
    //判断线程是否打断
    public boolean isInterrupted() {
            return isInterrupted(false);
    }
    //打断线程,其他线程可通过这个线程的句柄来打断
    public void interrupt() {
            if (this != Thread.currentThread())//如果不是当前线程则要判断是否有打断权限
                checkAccess();
    
            synchronized (blockerLock) {
                Interruptible b = blocker;
                if (b != null) {
                    interrupt0();           // Just to set the interrupt flag(这里我们可以看出 interrupt 仅仅是一个flag,并不能让线程停止)
                    b.interrupt(this);
                    return;
                }
            (
            interrupt0();
        }
    
    b)注意点,处于阻塞状态下的线程

    如果线程因为通过以下方法导致阻塞状态,将会抛出 InterruptedException 异常:

    wait(),wait(long),wait(long, int)
    join(),join(long),join(long, int) ,(本质因为wait导致)
    sleep(long),sleep(long, int)
    

    题目:执行完后会抛出打断异常吗?

    public static void main(String[] args)  {
            Thread thread = new Thread(()->{
                while (true);
            });
            thread.start();
    
            new Thread(()->{
                thread.interrupt();
            }).start();
    
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    

    以上方法显然无法抛出异常,因为thread.join() 是wait main线程,而非wait thread的线程,所以无法打断!
    需要注意,只有这个线程因为上述方法处于阻塞状态时,才会抛出打断异常!

    c)总结 interrupt模式结束线程

    如果线程被阻塞了,调用interrupt()我们可以在try-catch方法里面结束线程,如果线程没有阻塞,那么我们可以通过调用isInterrupted()来判断线程是否被打断,并结束线程

    相关文章

      网友评论

          本文标题:【多线程】重要的方法

          本文链接:https://www.haomeiwen.com/subject/tqyrdftx.html