线程信息的获取和设置,这里我们只讨论一些主要的信息,如:ID,name, priority,state。
一、ID和name信息的获取和设置
ID属性是JVM虚拟机为每一个新创建的线程分配的一个标识,不可更改,所以只提供了getId的方法获取ID,而没有设置ID的方法。
name属性是一个线程名字,与ID不同的是name属性是可以重复的。这个值是可以用户自定义的,当用户没有自定义时,JVM会为系统自动生成一个线程name。这个属性主要是方便用户使用的,例如在日志中输出线程的名称等等,易于理解和阅读。设置和获取name属性的方法,setName和getName。线程的名字可以在线程创建时设置,也可以在线程运行过程中设置。
public class ThreadTest04 {
public static void main(String[] args) {
ThreadThread threadThread1 = new ThreadThread(1);
threadThread1.setName("myThread");
ThreadThread threadThread2 = new ThreadThread(2);
threadThread2.setName("myThread");
System.out.println("threadThread1--ID: "+threadThread1.getId()+" threadThread1--name: "+threadThread1.getName());
System.out.println("threadThread2--ID: "+threadThread2.getId()+" threadThread2--name: "+threadThread2.getName());
}
}
//输出结果
//threadThread1--ID: 10 threadThread1--name: myThread
//threadThread2--ID: 11 threadThread2--name: myThread
priority表示线程的优先级,值是(1--10),当设置范围之外的数值时,会报非法参数异常。
这个优先级越高表示线程在获取CPU时间片时,具有更高的优先权。因此,在同样的工作量的情况下,优先级高的线程并不一定会早于优先级低的线程执行完成。只有在两个线程同时竞争CPU的时间片的时候,优先级高的线程可以优先获得CPU的时间片。如下面的代码:
public class ThreadTest04 {
public static void main(String[] args) {
//int availableProcessors = Runtime.getRuntime().availableProcessors();
Thread[] threads = new Thread[7];
for(int i=0; i<threads.length; i++){
threads[i]= new ThreadThread();
threads[i].setPriority(i+1);
if(i == 6){
threads[i].setPriority(Thread.MAX_PRIORITY);
}else{
threads[i].setPriority(Thread.MIN_PRIORITY);
}
}
for(int i=0; i<threads.length; i++){
threads[i].start();
}
}
}
代码中,创建了7个线程,将第七个线程的优先级设置为最大,其余六个线程设置为最小。但是运行代码你会发现,第七个线程有时候是第一个完成,有时候是最后一个完成,有时候在中间完成。
此外,在调用setPriority方法设置优先级的值时,无论你设置多少。优先级的最大值不会超过该线程所在线程组的优先级的值。即线程的优先级的值是小于等于线程组的优先级的值。示例:
public class ThreadTest05 {
public static void main(String[] args) {
ThreadGroup threadGroup = new ThreadGroup("myThreadGroup");
threadGroup.setMaxPriority(5); //设置线程组最大的优先级
ThreadThread threadThread = new ThreadThread(threadGroup,"myThread");
threadThread.setPriority(Thread.MAX_PRIORITY); //将线程的优先级设置为最大值,10
System.out.println(threadThread.getPriority()); //打印线程的优先级
}
}
执行上面的代码,你会发现控制台打印出来的值是5。这也就是上面说的线程的最大优先级是小于等于线程所在的线程组的优先级最大值的。
最后,线程的优先级可以是在线程创建时设置,也可以在线程启动之后进行设置。示例:
public class ThreadTest06 {
public static void main(String[] args) {
ThreadThread threadThread = new ThreadThread();
threadThread.setPriority(Thread.MAX_PRIORITY); //设置为最大值,10
System.out.println(threadThread.getPriority());
threadThread.start();
threadThread.setPriority(5); //设置为5
System.out.println(threadThread.getPriority());
}
}
上面代码的执行后,控制台会分别打印出10和5,也就是两次优先级设置都生效了。只是后一次设置会覆盖前一次的值。
三、state信息的获取
state表示线程执行的状态,只能读取,不能设置。线程执行的状态总共有6中:new,runnable,blocked,waiting,time_waiting,terminated。示例:
public class RunnableThread implements Runnable{
private int number;
public RunnableThread(int number) {
this.number = number;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadThread extends Thread{
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
//启动新线程,并等待其执行完成
RunnableThread runnableThread = new RunnableThread(1);
Thread thread = new Thread(runnableThread);
thread.start();
try {
thread.join(); //加入其它线程,只用thread线程执行完毕之后,才会继续往下执行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Thread : %s is End\n",Thread.currentThread().getName());
}
}
public class ThreadTest06 {
public static void main(String[] args) throws Exception {
ThreadThread threadThread = new ThreadThread();
State state1 = threadThread.getState();
System.out.println("state1--"+state1); //线程创建成功,但是没启动,状态:NEW
threadThread.start();
State state2 = threadThread.getState();
System.out.println("state2--"+state2); //线程启动了,状态:RUNNABLE
Thread.sleep(3000);
State state3 = threadThread.getState();
System.out.println("state3--"+state3); //线程中调用了sleep方法,等待了6秒,状态:TIMED_WAITING。注:因为sleep方法上加时间6秒,所以是TIMED_WAITING状态。如果是join这类会挂起线程,又没有设置时间的方法,线程的状态就是WAITING
Thread.sleep(4000);
State state4 = threadThread.getState();
System.out.println("state4--"+state4); //线程等待其他线程执行,且没有设置时间,状态:WAITING
Thread.sleep(5000);
State state5 = threadThread.getState();
System.out.println("state5--"+state5); //线程执行结束,状态:TERMINATED
}
}
关于block状态,是发生在线程需要获取锁的情况下的。线程等待锁的状态就是block状态。示例:
public class RunnableThread implements Runnable{
private int number;
public RunnableThread(int number) {
this.number = number;
}
@Override
public void run() {
getLock();
}
private synchronized void getLock() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadTest08 {
public static void main(String[] args) throws Exception {
RunnableThread runnableThread = new RunnableThread(1);
Thread thread1 = new Thread(runnableThread);
Thread thread2 = new Thread(runnableThread);
thread1.start();
Thread.sleep(1000);
thread2.start();
Thread.sleep(1000);
State state = thread2.getState(); //线程2等待锁,状态:BLOCKED
System.out.println("state--"+state); //因为线程1执行getLock方法等待了6秒钟,线程2去执行getLock方法时就需要等待线程1释放getLock方法的锁,此时线程2就是block状态
}
}