设置线程名称

调用Thread.currentThread().getName()来查看线程名。

没有任何设置,线程的名字是这样的:主线程叫做main,其他线程是Thread-x

守护线程

守护线程为其他线程服务的,如:垃圾回收线程就是守护线程。

守护线程有一个特点:当别的用户线程执行完了,虚拟机就会退出,守护线程也就会被停止掉了。也就是说,守护线程作为一个服务线程,没有服务对象就没有必要继续运行了。

注意:

1)在线程启动前设置为守护线程,方法setDaemon(boolean on),否则会抛出IllegalThreadStateException异常。

2)使用守护线程不要访问共享资源(数据库、文件等),因为它可能会在任何时候就挂掉了。

3)守护线程中产生的新线程也是守护线程。

public class MyThreadDemo{
   public static void main(String[] args){
       MyThread my=new MyThread();
       Thread t1=new Thread(my,"test1");
       Thread t2=new Thread(my,"test2");
       //设置为守护线程
       t2.setDaemon(true);
       t1.start();
       try{
          Thread.sleep(1000);
       }catch(InterruptedException ex){
          ex.printStackTrace();
       }
       t1.interrupt();
       System.out.println(Thread.activeCount());
       t2.start();
       System.out.println(Thread.currentThread().getName());
   }
}

class MyThread implements Runnable{
   public void run(){
       System.out.println(Thread.currentThread().getName());
   }
}

当t1线程执行完后,虚拟机就会退出,守护线程也就会被停止掉了,t2线程不会执行。

优先级线程

线程优先级仅仅表示线程获取的CPU时间片的几率高,但这不是一个确定的因素。

线程的优先级是高度依赖于操作系统的,Windows和Linux就有所区别。

java提供的优先级默认是5,最低是1,最高是10。

调用setPriority(int new Priority)来设置优先级。

线程的生命周期

线程有3个基本状态:执行、就绪、阻塞

1)sleep方法

调用sleep方法会进入计时等待状态,等时间到了,进入的是就绪状态而非是运行状态。

2)yield方法

调用yield方法会先让别的线程执行,但是不确保真正让出。

3)join方法

调用join方法,会等待该线程执行完毕后才执行别的线程。

4)interrupt方法

线程中断在之前的版本有stop方法,但是被设置过时了。强制线程终止,不安全,被设置过时了。现在,一般使用interrupt来请求终止线程。

注意:interrupt不会真正停止一个线程,它仅仅是给这个线程发了一个信号告诉它,它应该结束了。也就是说,java设计者实际上是想线程自己来终止,通过上面的信号,就可以判断处理什么业务了。具体到底中断还是继续运行,应该由被通知的线程自己处理。

Thread t1 = new Thread( new Runnable(){
    public void run(){
        // 若未发生中断,就正常执行任务
        while(!Thread.currentThread.isInterrupted()){
            // 正常任务代码……
        }
        // 中断的处理代码……
        doSomething();
    }
} ).start();

调用interrupt()并不是要真正终止掉当前线程,仅仅是设置了一个中断标志。所以interrupt方法压根是不会对线程的状态造成影响的,它仅仅设置一个标志位而已。

判断该线程是否被中断:

静态方法interrupted(),会清除中断标志位

实例方法isInterrupted(),不会清除中断标志位

 

如果阻塞线程调用了interrupt()方法,那么会抛出异常,设置标志位为false,同时该线程会退出阻塞的。

public class Main {
    /**
     * @param args
     */
    public static void main(String[] args) {
        Main main = new Main();

        // 创建线程并启动
        Thread t = new Thread(main.runnable);
        System.out.println("This is main ");
        t.start();

        try {

            // 在 main线程睡个3秒钟
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            System.out.println("In main");
            e.printStackTrace();
        }

        // 设置中断
        t.interrupt();
    }

    Runnable runnable = () -> {
        int i = 0;
        try {
            while (i < 1000) {

                // 睡个半秒钟我们再执行
                Thread.sleep(500);

                System.out.println(i++);
            }
        } catch (InterruptedException e) {


            // 判断该阻塞线程是否还在
            System.out.println(Thread.currentThread().isAlive());

            // 判断该线程的中断标志位状态
            System.out.println(Thread.currentThread().isInterrupted());

            System.out.println("In Runnable");
            e.printStackTrace();
        }
    };
}

执行的过程如下:

 

线程的生命周期与上述几种方法有关,调用上述方法后,线程的状态如图:

 

 

 

 

 

      

 posted on 2019-03-28 20:56  会飞的金鱼  阅读(101)  评论(0)    收藏  举报