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
的方法,线程释放锁,进入WAITING
或TIMED_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);
}
}
}