• 150455

    文章

  • 1009

    评论

  • 13

    友链

  • 最近新加了换肤功能,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

Java多线程(二):线程的相关操作


2.1 线程的生命周期

2.1.1 新建和就绪

  • 新建状态:new一个线程对象后,就是新建状态。

    注意:这里只是创建了一个Thread对象,就是一个普通的Java对象,没有表现出任何线程的动态特征,因此这里并非创建新线程。

  • 就绪状态:当调用start()后,才真正地创建新线程,系统内把run()当作线程体,表示该线程可以运行了,进入就绪状态。

    注意:如果直接调用run(),并不能启动线程,这时的run()就是一个普通的Java方法,并且在该方法中不能直接使用Thread的相关方法;并且此时该线程已经不再处于新建状态,不能再次调用start()

2.1.2  运行和阻塞

2.1.3 死亡

  • 进入死亡状态的方式:
  1. run()call()方法执行完,线程正常结束。
  2. 下层抛出未捕获的异常或错误。
  3. 直接调用Thread.stop()方法结束线程:该方法会直接终止线程,并立即释放这个线程持有的所有锁,因此可能会导致数据不一致问题,已废弃。
  • 线程死亡是不可逆的。
  • 安全地终止线程的两种方式:
    1. 使用boolean变量。
    2. 使用中断。

范例:

public class ShutDown{

   private static class Run implements Runnable{

       private long i;

       private boolean flag = true;

       @Override

       public void run() {

           //方式1:利用Boolean变量

           //方式2:利用中断

           while(flag && !Thread.currentThread().isInterrupted()){

               i++; //正常执行线程逻辑。

           }

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

       }

       public void calcle(){

           flag = false;

       }

   }

  

   public static void main(String[] args) throws Exception {

       Run one = new Run();

       Thread countThread = new Thread(one, "CountThread");

       countThread.start();

       TimeUnit.SECONDS.sleep(1);

       //方式2:利用中断

       countThread.interrupt();

       //count i = 785844152

      

       Run two = new Run();

       countThread = new Thread(two, "CountThread");

       countThread.start();

       TimeUnit.SECONDS.sleep(1);

       //方式1:利用Boolean变量

       two.calcle();

       //count i = 791844688

   }

}

2.2 后台线程

  • Thread类:

        void setDaemon(boolean on); //ontrue时,将该线程设置为守护线程(必须在该线程start之前,否则会引发异常)

        boolean isDaemon(); //判断是否为守护线程。

  • 又称守护线程、精灵线程,它的任务是为其他线程提供服务。JVM的垃圾回收线程就是典型的后台线程。
  • 如果所有的前台线程都死亡,后台线程会自动死亡。
  • 当虚拟机中只剩下后台线程时,虚拟机退出。

2.3 线程的休眠与谦让、挂起与继续执行

2.3.1 sleep()休眠与yield()谦让

  • 两者均是Thread静态方法:

        static void sleep(long millis);

        static void sleep(long millis, int nanos);

        static void yield(); 

  • 比较
    1. sleep()暂停线程后,会给其他线程执行机会,不理会其他线程的优先级;yield()只会给优先级大于等于自身的线程机会。二者均不会释放锁
    2. sleep()会将线程转入阻塞状态,阻塞时间结束后进入就绪状态;yield()是将线程转入就绪状态,完全有可能刚被yield()暂停,又立即获得执行机会。
    3. sleep()声明抛出了异常,所以调用时要么捕获该异常,要么显式抛出,而yield()没有。
    4. sleep()有更好的可移植性,推荐使用。

2.3.2 suspend()挂起与resume()继续执行

  • 两者均是Thread的方法

        void suspend();

        void resume();

  • suspend()暂停线程后不会释放任何资源,直到其他线程上执行了resume(),被挂起的线程才能继续执行。但是如果意外地,resume()suspend()之前执行了,那么被挂起的线程就很难有机会再继续执行。
  • 已弃用

2.4 线程的优先级

  • Thread中的方法和静态常量:

        void setPriority(int newPriority); //newPriority范围是1~10,数字越大优先级越高,也可以用下面的三个常量。

        static int MAX_PRIORITY; //线程可以拥有的最大优先级,10

        static int MIN_PRIORITY; //线程可以拥有的最小优先级,1

        static int NORM_PRIORITY; //分配给线程的默认优先级,5

  • 优先级高的线程并不一定在低优先级线程之前执行,还和OS有关。

2.5 线程的中断

  • 线程中断并不会使线程立即退出,而是给线程发送一个通知,告知目标线程。至于目标线程接到通知后如何处理,完全由目标线程自行决定。线程通过检查自身是否被中断来进行响应。
  • Thread中方法

        public void interrupt(); //中断线程,即设置中断标记位。

        public boolean isInterrupted(); //判断是否被中断。

        public static boolean interrupted(); //判断是否被中断,并清除中断标志位。

  • 中断异常:InterruptedException:大部分迫使线程等待的方法均会抛出该异常,该异常不是运行时异常,即程序必须捕获并处理它,并且会清除中断标志位。总结如下:

        public static native void Thread.sleep() throws InterruptedException; //会清除中断标记位,为了捕捉到中断,需要在异常处理中再次设置中断标记位。

        public final void Object.wait() throws InterruptedException;

        public final void Thread.join() throws InterruptedException;

        public static native Thread.yield(); //不响应中断。

        public void Condition.await() throws InterruptedException;

        public void Condition.awaitUninterruptibly(); //不响应中断。

        public void Semaphore.acquire() throws InterruptedException;

        public void Semaphore.acquireUninterruptibly(); //不响应中断。

        public void CountDownLatch.await() throws InterruptedException;

        public void CyclicBarrier.await() throws InterruptedException BrokenBarrierExceptiion;

        public static void LockSupport.park(); //响应中断,但不抛出InterruptedException异常,且可以获得中断标记位。


695856371Web网页设计师②群 | 喜欢本站的朋友可以收藏本站,或者加入我们大家一起来交流技术!

0条评论

Loading...


发表评论

电子邮件地址不会被公开。 必填项已用*标注

自定义皮肤 主体内容背景
打开支付宝扫码付款购买视频教程
遇到问题联系客服QQ:419400980
注册梁钟霖个人博客