java多线程(1) ----- java多线程技能(下)

(欢迎关注微信公众号:深入Java底层)

1、停止线程

1.1 停止不了的线程

调用interrupt()方法仅仅是在当前线程中打了一个停止的标记,并不是真的停止线程

1.2 判断线程是否是停止状态

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

package t12;

publicclass MyThread extends Thread {

       @Override

       publicvoid run() {

              super.run();

              for(int i=0;i<500000;i++){

                     System.out.println("i="+ (i+1));

              }

       }

}

package t12;

publicclass Run2 {

       /**

        * @param args

        */

       publicstaticvoidmain(String[] args) {

         //thread.interrupt();

              Thread.currentThread().interrupt();

              System.out.println("是否停止1 =" + Thread.interrupted());

              System.out.println("是否停止2 =" + Thread.interrupted());

              System.out.println("end!");

       }

}

运行结果:

//thread.interrupt();

是否停止1 =false

是否停止2 =false

end!

// Thread.currentThread().interrupt();

是否停止1 =true

是否停止2 =false

end!

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

package t12;

publicclass Run3 {

       /**

        * @param args

        */

       publicstaticvoidmain(String[] args) {

              try {

                     MyThreadthread = new MyThread();

                     thread.start();

                     Thread.sleep(1000);

                     thread.interrupt();

                     //Thread.currentThread().interrupt();

                     System.out.println(" 是否停止1 =" +thread.isInterrupted());

                     System.out.println(" 是否停止2 =" +thread.isInterrupted());

              } catch(InterruptedException e) {

                     System.out.println("maincatch");

                     e.printStackTrace();

              }

              System.out.println("end!");

       }

}

运行结果:

//thread.interrupt();

是否停止1 =true

是否停止2 = true

end!

1.3 异常法停止的线程

在线程中用for语句来判断一下线程是否停止状态,如果是停止状态,则后面的代码不再运行即可。但如果for语句下面还有语句,还是会继续运行。使用“抛异常”的方法可以解决上面的问题,参看如下代码

package t13_1;

publicclass Run {

       publicstaticvoidmain(String[] args) {

              try {

                     MyThreadthread = new MyThread();

                     thread.start();

                     Thread.sleep(2000);

                     thread.interrupt();

              } catch(InterruptedException e) {

                     System.out.println("maincatch");

                     e.printStackTrace();

              }

              System.out.println("end!");

       }

}

package t13_1;

publicclass Run {

       publicstaticvoidmain(String[] args) {

              try {

                     MyThreadthread = new MyThread();

                     thread.start();

                     Thread.sleep(2000);

                     thread.interrupt();

              } catch(InterruptedException e) {

                     System.out.println("maincatch");

                     e.printStackTrace();

              }

              System.out.println("end!");

       }

      

       /**

        * 运行结果:

        * ...

           i=352988

              i=352989

              i=352990

              i=352991

              i=352992

              i=352993

              已经停止状态了,我要退出了

              end!

              MyThread.javarun方法中的catch了!

              java.lang.InterruptedException

                     att13_1.MyThread.run(MyThread.java:11)

        *

        */

}

1.4 在沉睡中停止

如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变成false;

package t14;

publicclass MyThread extends Thread {

       @Override

       publicvoid run() {

              super.run();

              try{

                     System.out.println("runbegin");

                     Thread.sleep(200000);

                     System.out.println("runend");

              }catch(InterruptedExceptione){

                     System.out.println("在沉睡中被停止!进入catch!" + Thread.interrupted());

                     e.printStackTrace();

              }

       }

}

package t14;

publicclass Run {

       /**

        * @param args

        */

       publicstaticvoidmain(String[] args) {

              try {

                     MyThreadthread = new MyThread();

                     thread.start();

                     Thread.sleep(200);

                     thread.interrupt();

              } catch(InterruptedException e) {

                     System.out.println("maincatch");

                     e.printStackTrace();

              }

              System.out.println("end!");

       }

       /**

        * 运行结果:

        * run begin

          end!

             在沉睡中被停止!进入catch!false

          java.lang.InterruptedException: sleepinterrupted

                at java.lang.Thread.sleep(Native Method)

                at t14.MyThread.run(MyThread.java:10)

        *

        */

}

如果先interrupt()然后再sleep,也会进入catch语句,并且清除停止状态值,使之变成false。

package t15;

publicclass MyThread extends Thread {

       @Override

       publicvoid run() {

              super.run();

              try{

                     for(inti=0;i<100000;i++){

                            System.out.println("i="+(i+1));

                     }

                     System.out.println("runbegin");

                     Thread.sleep(200000);

                     System.out.println("runend");

              }catch(InterruptedExceptione){

                     System.out.println("先停止!再遇到了sleep!进入catch!"+ Thread.interrupted());

                     e.printStackTrace();

              }

       }

       /**

        * interrupt()然后再sleep,也会进入catch语句,并且清除停止状态值。

        *

        */

}

package t15;

publicclass Run {

       /**

        * @param args

        */

       publicstaticvoidmain(String[] args) {

              MyThreadthread = new MyThread();

              thread.start();

              thread.interrupt();

              System.out.println("end!");

       }

      

       /**

        * 运行结果:

    …………….

        * i=99995

              i=99996

              i=99997

              i=99998

              i=99999

              i=100000

              runbegin

              先停止!再遇到了sleep!进入catch!false

              java.lang.InterruptedException:sleep interrupted

                     atjava.lang.Thread.sleep(Native Method)

                     att15.MyThread.run(MyThread.java:13)

        *

        */

}

1.5 使用return停止线程

    将方法interrupt()与return结合使用也能实现停止线程的效果。不过还是建议使用“抛异常”的方法来实现线程的停止,因为在catch块中还可以将异常向上抛,使线程停止的事件得以传播。

2. yield方法

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

3. 线程的优先级

在操作系统中,线程可以划分优先级,优先级较高的线程得到

的CPU资源较多,也就是CPU优先执行优先级较高的线程对象中任务。

在Java中,线程的优先级具有继承性,比如A线程启动B线程,则B线程的优先级与A是一样的。如果A线程的优先级被更改,B线程将继承更改。

package t18;

publicclass MyThread1 extends Thread {

       @Override

       publicvoid run() {

              System.out.println("MyThread1run priority=" + this.getPriority());

              MyThread2thread2 = new MyThread2();

              thread2.start();

       }

 

}

package t18;

publicclass MyThread2 extends Thread {

       @Override

       publicvoid run() {

              System.out.println("MyThread2run priority=" + this.getPriority());

       }

}

package t18;

publicclass Run {

       /**

        * @param args

        */

       publicstaticvoidmain(String[] args) {

              System.out.println("mainthread begin priority=" + Thread.currentThread().getPriority());

//           Thread.currentThread().setPriority(6);

              System.out.println("mainthread begin priority=" + Thread.currentThread().getPriority());

              MyThread1thread1 = new MyThread1();

              thread1.start();

       }

    /**

     * 运行结果:

     *  main thread begin priority=5

              mainthread begin priority=5

              MyThread1run priority=5

              MyThread2run priority=5

     *

     * 去掉注释,运行结果:

     *  main thread begin priority=5

              mainthread begin priority=6

              MyThread1run priority=6

              MyThread2run priority=6

     *

     *

     * java中,线程的优先级具有继承性,比如A线程启动B线程,则B线程的优先级与A是一样的。

     */

}

线程的优先级具有一定的规则性,也就是CPU尽量将执行资源让给优先级比较高的线程,但优先级较高的线程并不一定每一次都先执行完,线程的优先级还具有“随机性”。优先级高的运行得快,但是测试的时候好多次并没有更快。

4. 守护线程

在Java线程中两种线程,一种是用户线程,另一种是守护线程。

守护线程是一种特殊的线程,当线程中不存在非守护线程了,则守护线程自动销毁。典型的守护线程就是垃圾回收线程,当进程中没有非守护线程了,则垃圾回收线程也就没有存在的必要了,自动销毁。Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是GC(垃圾回收器),它就是一个很称职的守护者。

(欢迎关注微信公众号:深入Java底层)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值