Java高并发程序-Chapter2 Java并行程序基础 (第七讲)线程组 、守护线程、线程优先级

时间:2022-12-25 10:42:35

1.线程组 

线程分门别类的管理

package com.john.learn.high.concurent.chapter02.group;

public class ThreadGroupName implements Runnable{

  
  public void run() {
    
    String groupAndName = Thread.currentThread().getThreadGroup().getName()+"-" + Thread.currentThread().getName();
    
    while(true) {
     System.out.println("I am " + groupAndName);
     
     try {
       Thread.sleep(10000);
     } catch (InterruptedException e) {
       
       e.printStackTrace();
     }
    }
  }
  
  public static void main(String[] args) {
    
    ThreadGroup tg = new ThreadGroup("PrintGroup");
    
    Thread t1 = new Thread(tg, new ThreadGroupName(), "t1");
    Thread t2 = new Thread(tg, new ThreadGroupName(), "t2");
    
    t1.start();
    t2.start();
    
    System.out.println("Active Thread Count:" + tg.activeCount());
    
    tg.list();

  }

}


线程组还有一个值得注意的方法 stop 它会停止线程组中所有的线程。这看起来是一个很方便的功能,但是它会遇到和 Thread. stop(相同的问题,因此使用时也需要格外谨慎)

强烈建议大家在创建线程和线程组的时候,给它们取一个好听的名字

2. 守护线程

守护线程是一种特殊的线程,就和它的名字一样,它是系统的守护者,在后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程就可以理解为守护线程。
守护线程要守护的对象已经不存在了,那么整个应用程序就自然应该结束。

因此,当一个Java应用内,只有守护线程时,Java虚拟机就会自然退出

package com.john.learn.high.concurent.ch02.deamon;

public class DaemonCase {

	public static class DaemonThread extends Thread {

		public DaemonThread(boolean daemon) {
			super("A daemon thread");
			setDaemon(daemon);
		}

		@Override
		public void run() {

			while (true) {

				System.out.println("I am live, but I am a daemon thread!");

				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {

				}
			}
		}

	}
	
	public static void main(String[] args) throws InterruptedException {
		
		//setDaemon(true);
		DaemonThread thread = new DaemonThread(true);
		thread.start();
		
		Thread.sleep(2000);
		
		System.out.println("Main Thread exit! 所有daemon线程将结束!");
	}

}

当DaemonThread 是一个守护线程时(setDaemon(true)), 主线程结束后, daemon线程自动结束。

如果DaemonThread thread = new DaemonThread(false);

Main线程不会自动关闭,由于DaemonThread  还没有结束!

3. 线程优先级

优先级高的线程在竞争资源时会更有优势,更可能抢占资源,当然,这只是一个概率问题。
如果运气不好,高优先级线程可能也会抢占失败。由于线程的优先级调度和底层操作系统有密切的关系,在各个平台上表现不一,并且这种优先级产生的后果也可能不容易预测,无法精准控制,比如一个低优先级的线程可能一直抢占不到资源从而始终无法运行,而产生饥饿(虽然优先级低,但是也不能饿死它呀)。
囚此,在要求严格的场合,还是需要白己在应用层解决线程调度问题。


在Java中,使用1到10表示线程优先级。一般可以使用内置的三个静态标量表示


 public final static int MIN PRIORITY =1
 public final static int NORM PRIORITY=5
 public final static int MAX PRIORITY=10


数字越大则优先级越高,但有效范围在1到10之间 


package com.john.learn.high.concurent.ch02.priority;

public class PriorityDemo {

	public static class PriorityThread extends Thread {

		public PriorityThread(String name, int priority) {
			super(name);
			setPriority(priority);
		}
		
		@Override
		public void run() {
			
			int count = 0;
			
			while(true) {
				
				synchronized (PriorityDemo.class) {
					
					count++;
					
					if(count >100000000) {
						
						System.out.println(Thread.currentThread().getName() + " is completed!");
						break;
					}
				}
			}
			
			
		}

	}
	
	public static void main(String[] args) {
		
		PriorityThread highPriorityThread
		 = new PriorityThread("High Priority Thread", Thread.MAX_PRIORITY);
		
		PriorityThread lowPriorityThread
		 = new PriorityThread("Low Priority Thread", Thread.MIN_PRIORITY);
		
		highPriorityThread.start();
		lowPriorityThread.start();
		
	}
}