• 二.多线程技能


    1.停止线程

      停止线程是多线程开发很重要的技术点,掌握此技术可以对线程的停止惊醒有效的处理。

      停止一个线程可以使用Thread.stop()方法,但最好不要使用它,这个方法是不安全的。

      大多数停止一个线程使用的是Thread.interrupt()方法,尽管方法的名称是“停止,中止”,但这个方法不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的停止。

    停止不了的线程

      本例将调用inrerupt()方法来停止线程,但interrupt方法的使用效果并不像for+break那样,马上停止循环。调用interrupt方法仅仅是在当前线程中打了一个停止的标记,并不是真的停止线程。

    判断线程是否是停止状态

    Thread中

       this.interrupted()测试当前线程是否已经中断,执行后具有将状态标识置为false的功能。 

      this.isInterrupted()测试线程Thread是否已经是中断状态,但不清除状态标识。

     先来测试interrupted();

      

    类Run.java中虽然是在Thread对象上调用一下代码:

      thread.interrupt();

    来停止thread对象所代表的线程,在后面又使用

    来判断thread对象所代表的线程是否停止,但从控制台打印的结果来看并未停止,这也就证明了interrupted方法测试的是当前线程是否已经中断。这个当前线程就是main,它从未中断过,所以打印的是两个false;

     再来看看IsInterrupted()方法

      

     

    1、interrupt 
    interrupt方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。
    注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。支持线程中断的方法(也就是线程中断后会抛出interruptedException的方法)就是在监视线程的中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。

    2、interrupted 和 isInterrupted

    首先看一下该方法的实现:
    1 public static boolean interrupted () {
    2      return currentThread().isInterrupted(true);
    3 }
    该方法就是直接调用当前线程的isInterrupted(true)方法。
    然后再来看一下 isInterrupted的实现:
    1 public boolean isInterrupted () {
    2      return isInterrupted( false);
    3 }
    这两个方法有两个主要区别:
    1. interrupted 是作用于当前线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。例如我们可以在A线程中去调用B线程对象的isInterrupted方法。)
    2. 这两个方法最终都会调用同一个方法,只不过参数一个是true,一个是false;
     
    第二个区别主要体现在调用的方法的参数上,让我们来看一看这个参数是什么含义
     
    先来看一看被调用的方法 isInterrupted(boolean arg)的定义:
    1 private native boolean isInterrupted( boolean ClearInterrupted);
    原来这是一个本地方法,看不到源码。不过没关系,通过参数名我们就能知道,这个参数代表是否要清除状态位。

    如果这个参数为true,说明返回线程的状态位后,要清掉原来的状态位(恢复成原来情况)。这个参数为false,就是直接返回线程的状态位。

    这两个方法很好区分,只有当前线程才能清除自己的中断位(对应interrupted()方法)

    是不是这样理解呢,
    Thread.currentThread().interrupt(); 这个用于清除中断状态,这样下次调用Thread.interrupted()方法时就会一直返回为false,因为中断标志已经被恢复了。
    而调用isInterrupted 只是简单的查询中断状态,不会对状态进行修改。

    interrupt()是用来设置中断状态的。返回true说明中断状态被设置了而不是被清除了。我们调用sleep、wait等此类可中断(throw InterruptedException)方法时,一旦方法抛出InterruptedException,当前调用该方法的线程的中断状态就会被jvm自动清除了,就是说我们调用该线程的isInterrupted 方法时是返回false。如果你想保持中断状态,可以再次调用interrupt方法设置中断状态。这样做的原因是,java的中断并不是真正的中断线程,而只设置标志位(中断位)来通知用户。如果你捕获到中断异常,说明当前线程已经被中断,不需要继续保持中断位。
    interrupted是静态方法,返回的是当前线程的中断状态。例如,如果当前线程被中断(没有抛出中断异常,否则中断状态就会被清除),你调用interrupted方法,第一次会返回true。然后,当前线程的中断状态被方法内部清除了。第二次调用时就会返回false。如果你刚开始一直调用isInterrupted,则会一直返回true,除非中间线程的中断状态被其他操作清除了。
     

    能停止的线程——一异常法

    异常中断

    抛出InterruptedException()异常,然后捕捉异常

    在沉睡中中止

     如果线程在sleep()状态下停止线程会是什么效果呢?

    线程被终止,“run end“没有打印出来

    前一个实验室先Sleep然后interrupt()停止,与之想法的操作在学习线程也要注意

    先interrupt然乎再sleep

     

    当再主线程中调用了interrup后,遇到sleep会触发inerruptExceptiony异常。

    暴力停止

    使用stop()方法停止线程是非常暴力的。

    调用stop()方法会抛出ThreadDeath异常,但在通常的情况下,此异常不需要显示的捕捉。

    使用stop()释放锁会给数据造成不一致性的结果。所以不要使用stop();

    使用return停止线程

    使用interrupt()与return结合使用也能实现停止线程的效果

     

     

    2.暂停线程

     暂停线程以为着此线程可以恢复运行。在java多线程中,可以使用supsend()方法暂停线程,使用resumen()方法来回复线程的执行

     suspend和resume方法的使用

     

     suspend()和resume()方法的缺点——独占

    在使用suspend和resume方法时,如果使用不当,极易造成公共的同步对象的独占,使其他线程无法访问公共同步对象。

    supsend作废的原因DEMO

     

     

    出现这样情况的原因是,当程序运行到println()方法时,同步所未被释放。这导致当前PrintStream对象println方法一直呈“”暂停状态。

    所以main()方法中的代码无法打印。

     

    suspend和resume方法的缺点——不同步

    yield方法

    yield()方法的作用是放弃当前的CPU资源,将它让给其它的任务去占用CPU执行时间。但放弃的时间不确定,有可能刚刚放弃,马上又获得CpU时间片。

  • 相关阅读:
    Subclipse安装及应用【eclipse 3.7 + subclipse1.8】
    淘宝有病!
    集装箱货柜号码 公式算法
    自己网站利用支付宝结算时的说明
    发现安全卫士360影响电脑正常运行
    中国银行的动态口令
    c#中的接口(interface)到底应用在哪些地方?
    淘宝有病(二)
    What 's CATT(Computer Aided Test Tool)?How to deal with the CATT in the SAP System?什么是CATT(计算机附加测试工具)
    Consultanting Service
  • 原文地址:https://www.cnblogs.com/duan2/p/7603338.html
Copyright © 2020-2023  润新知