Thread线程管理·获取和设置线程信息·线程状态解析

版权声明:本文为博主原创文章,未经博主允许不得转载。如果你非要转载,麻烦加上我的原网址,谢谢。http://blog.csdn.net/qinglingLS https://blog.csdn.net/qinglingLS/article/details/88650978

Thread获取和设置线程信息

Thread类的对象中保存了一些属性信息能够帮助我们来辨别每一个线程,知道它的状态,调整控制其优先级。 这些属性是:
ID: 每个线程的独特标识。
Name: 线程的名称。
Priority: 线程对象的优先级。优先级别在1-10之间,1是最低级,10是最高级。不建议改变它们的优先级,但是你想的话也是可以的。

如果在这里如果你设置的优先级不是在1-10之间
setPriority() 方法会抛出 IllegalArgumentException 异常

Status: 线程的状态。在Java中,线程只能有这6种中的一种状态: new, runnable, blocked, waiting, time waiting, 或 terminated.

实现线程可以有多种方法,比较推荐的是实现Runnable接口:

public class Calculator implements Runnable {}

然后再在main()方法里面调用:
创建一个 Calculator 类的对象,  一个Thread类的对象,
 然后传递 Calculator 对象作为thread类构造函数的参数,
 最后调用线程对象的start() 方法。

创建一个Thread类的对象不会创建新的执行线程。
同样,调用实现Runnable接口的 run()方法也不会创建一个新的执行线程。
只有调用start()方法才能创建一个新的执行线程。
但是当然也要了解其他创建方式:

直接继承thread类,然后覆盖run()方法。

当全部的线程执行结束时(更具体点,所有非守护线程结束时),Java程序就结束了。如果初始线程(执行main()方法的主线程)运行结束,其他的线程还是会继续执行直到执行完成。但是如果某个线程调用System.exit()指示终结程序,那么全部的线程都会结束执行。

使用Thread.State[]来获取线程状态信息

Thread.State status[]=new Thread.State[10];
private static void writeThreadInfo(PrintWriter pw, Thread thread, State state) {
   pw.printf("Main : Id %d - %s\n",thread.getId(),thread.getName());
   pw.printf("Main : Priority: %d\n",thread.getPriority());
   pw.printf("Main : Old State: %s\n",state);
   pw.printf("Main : New State: %s\n",thread.getState());
   pw.printf("Main : ************************************\n");
}

参考网址:http://ifeve.com/java-7-concurrency-cookbook/

java线程状态

java线程状态在Thread中定义,源码中能看到有个枚举State,总共定义了六种状态:
NEW: 新建状态,线程对象已经创建,但尚未启动
RUNNABLE:就绪状态,可运行状态,调用了线程的start方法,已经在java虚拟机中执行,等待获取操作系统资源如CPU,操作系统调度运行。
BLOCKED:堵塞状态。线程等待锁的状态,等待获取锁进入同步块/方法或调用wait后重新进入需要竞争锁
WAITING:等待状态。等待另一个线程以执行特定的操作。调用以下方法进入等待状态。 Object.wait(), Thread.join(),LockSupport.park
TIMED_WAITING: 线程等待一段时间。调用带参数的Thread.sleep, objct.wait,Thread.join,LockSupport.parkNanos,LockSupport.parkUntil
TERMINATED:进程结束状态。
Thread.sleep(long)使线程暂停一段时间,进入TIMED_WAITING时间,并不会释放锁,在设定时间到或被interrupt后抛出InterruptedException后进入RUNNABLE状态;

Thread.join是等待调用join方法的线程执行一段时间(join(long))或结束后再往后执行,被interrupt后也会抛出异常,join内部也是wait方式实现的。
wait方法是object的方法,线程释放锁,进入WAITINGTIMED_WAITING状态。等待时间到了或被notify/notifyall唤醒后,回去竞争锁,如果获得锁,进入RUNNABLE,否则进步BLOCKED状态等待获取锁。

注意这里很容易导致死锁,写的时候需要反复思量。

下面是一个小例子,主线程中调用多线程,等待超时后如果子线程还未结束,则中断子线程(interrupt)。
在这里插入图片描述在这里插入图片描述
参考网址:https://baijiahao.baidu.com/s?id=1574105592023615&wfr=spider&for=pc

总结

一个线程运行的流程(无等待情况下):
由.start()开始,进入new状态,到blocked,到runnable再到terminated。
在这里插入图片描述
在这里插入图片描述

运行示例代码:
test1.Main.class

package test1;

import java.io.FileWriter;
import java.io.PrintWriter;
import java.lang.Thread.State;

public class Main {
  public static void main(String[] args) {
    Thread threads[] = new Thread[10];
    Thread.State status[] = new Thread.State[10];

    for (int i = 0; i < 10; i++) {
      threads[i] = new Thread(new ThreadTest(i));
      if ((i % 2) == 0) {
        threads[i].setPriority(Thread.MAX_PRIORITY);
      } else {
        threads[i].setPriority(Thread.MIN_PRIORITY);
      }
      threads[i].setName("Thread " + i);
    }

    try (FileWriter file = new FileWriter("log.txt");
        PrintWriter pw = new PrintWriter(file);) {
      for (int i = 0; i < 10; i++) {
        pw.println(
            "Main : Status of Thread " + i + " : " + threads[i].getState());
        status[i] = threads[i].getState();
      }
      for (int i = 0; i < 10; i++) {
        threads[i].start();
      }
      boolean finish = false;
      while (!finish) {
        for (int i = 0; i < 10; i++) {
          if (threads[i].getState() != status[i]) {
            writeThreadInfo(pw, threads[i], status[i]);
            status[i] = threads[i].getState();
          }
        }
        finish = true;
        for (int i = 0; i < 10; i++) {
          finish = finish && (threads[i].getState() == State.TERMINATED);
        }
      }

    } catch (Exception e) {
      // TODO: handle exception
    }

  }

  private static void writeThreadInfo(PrintWriter pw, Thread thread,
      State state) {
    pw.printf("Main : Id %d - %s\n", thread.getId(), thread.getName());
    pw.printf("Main : Priority: %d\n", thread.getPriority());
    pw.printf("Main : Old State: %s\n", state);
    pw.printf("Main : New State: %s\n", thread.getState());
    pw.printf("Main : ************************************\n");

  }
}

test.ThreadTest.class

package test1;

public class ThreadTest implements Runnable {
  private int number;

  public ThreadTest(int number) {
    this.number = number;
  }

  @Override
  public void run() {
    for (int i = 1; i <= 10; i++) {
      System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(),
          number, i, i * number);
    }
  }

}

猜你喜欢

转载自blog.csdn.net/qinglingLS/article/details/88650978