线程的管理
当我们在一个系统中使用了非常之多的线程的时候,就非常不方便去管理,于是乎,设计者便设计了一个名为线程组的类,去好好的管理线程。线程组类的名字叫做ThreadGroup
1 2 3 4 5
| ThreadGroup tg=new ThreadGroup("printGroup");
Thread t1=new Thread(tg,"T1"); Thread t2=new Thread(tg,"T2");
|
我们看看这个thread的构造函数和别的有什么不同吧
1 2 3
| public Thread(ThreadGroup group, Runnable target, String name) { init(group, target, name, 0); }
|
可以看到,这里第一个要传入的参数叫ThreadGroup类,第三个叫名字,表示这个线程属于什么什么线程组,什么什么名字。
1 2 3 4
| tg.activeCount()
tg.list();
|
最后运行一段程序看看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class test implements Runnable{ public static void main(String[] args){ ThreadGroup tg=new ThreadGroup("printGroup"); Thread t1=new Thread(tg,new test(),"T1"); Thread t2=new Thread(tg,new test(),"T2"); t1.start(); t2.start(); System.out.println(tg.activeCount()); tg.list();
} @Override public void run() { String group=Thread.currentThread().getThreadGroup().getName()+"-"+Thread.currentThread().getName(); while (true){ System.out.println("i am "+group); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
2 i am printGroup-T1 i am printGroup-T2 java.lang.ThreadGroup[name=printGroup,maxpri=10] Thread[T1,5,printGroup] Thread[T2,5,printGroup]
|
线程的后台
这里的后台不是指靠山的意思,就是单纯的后台,每个活动都会有后台,很多次要的事物,都是在幕后运行的。比如一家饭馆,等客人就是主场,服务员就是后台,等主场人走光了,后台也就不必继续服务了,这里说线程的后台,就是指的这个意思。有些主线程在不断的消耗资源进行运算,而后台线程则负责资源垃圾的回收,等主线程结束以后,后台线程便会自然结束。
设置后台线程的方法很简单
1 2 3 4
| Thread t1= new Thread(new test()); t1.setDaemon(true); t1.start();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class test { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new test1()); Thread t2 = new Thread(new test2()); t1.setDaemon(true); t2.start(); t1.start(); } public static class test1 implements Runnable { @Override public void run() { while (true) { System.out.println("i am alive"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
public static class test2 implements Runnable {
@Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } }
}
i am alive i am alive i am alive i am alive i am alive
|
如上述代码块所示,线程便会在运行后,开始寻找主线程,等待主线程,如果发现没有主线程,或主线程已经结束,只有后台线程才存活,便会结束线程。
线程的优先级
从上面可以看到,线程与线程之间存在着主次关系,那么主线程与主线程之间也有高低之分吗?答案是有的。为了更好的完成线程之间的调度问题,必然有方法也可以控制着线程的优先级,最常用的方式就是主动的去设置线程的优先级setPriority()
1 2 3 4 5 6 7 8 9 10 11 12 13
| public final void setPriority(int newPriority) { ThreadGroup g; checkAccess(); if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } if((g = getThreadGroup()) != null) { if (newPriority > g.getMaxPriority()) { newPriority = g.getMaxPriority(); } setPriority0(priority = newPriority); } }
|
在这个方法中传入一个数字,代表着线程的优先级,优先级更高的线程便拥有着更高的资源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public class test { public static class high implements Runnable { static int count=0; @Override public void run() { while (true){ synchronized (test.class){ count++; if (count>10000){ System.out.println("high is win"); break; } }}
} } public static class low implements Runnable{ static int count=0; @Override public void run() { while (true){ synchronized (test.class){ count++; if (count>10000){ System.out.println("low is win"); break; } }}
} }
public static void main(String[] args) { Thread t1= new Thread(new high()); Thread t2= new Thread(new low()); t1.setPriority(10); t2.setPriority(1); t1.start(); t2.start(); } }
high is win low is win
|
但我们常说事无绝对,哪怕是再冰冷的机器也是如此,设置优先级并不代表一定会优先获得,只不过是获得的概率比较大而已,再多试试几次,也会有低优先级的线程先执行完的时候。