1、线程的状态
线程对象在不同的运行时期有不同的状态,状态信息就存在于State枚举类中
Thread.State :
NEW :至今尚未启动的线程
RUNNABLE:正在java虚拟机中执行的线程
BLOCKED:受阻塞于并等待某个监视器锁的线程
WAITING:无限期的等待另一个线程来执行某一个特定操作的线程
TIMED_WAITING:等待另一个线程来执行某一特定操作的线程
TERMINATED:已退出的线程
package com.threadTest.thread.add.state.test01; /** * Created by sky on 2017/3/23. */ public class Run { public static void main(String[] args) { try { MyThread thread01 = new MyThread(); System.out.println("main 方法中的状态1: " + thread01.getState()); Thread.sleep(1000); thread01.start(); Thread.sleep(1000); System.out.println("main 方法中的状态2: " + thread01.getState()); MyThread thread02 = new MyThread(); System.out.println("main 方法中的状态1: " + thread02.getState()); Thread.sleep(1000); thread02.start(); Thread.sleep(1000); System.out.println("main 方法中的状态2: " + thread02.getState()); } catch (InterruptedException e) { e.printStackTrace(); } } }
输出:
构造方法中的状态1: RUNNABLE
构造方法中的状态2: RUNNABLE
main 方法中的状态1: NEW
run 构造方法中的状态1: RUNNABLE
main 方法中的状态2: TIMED_WAITING
构造方法中的状态1: RUNNABLE
构造方法中的状态2: RUNNABLE
main 方法中的状态1: NEW
run 构造方法中的状态1: RUNNABLE
main 方法中的状态2: TIMED_WAITING
package com.threadTest.thread.add.state.test01; /** * Created by sky on 2017/3/23. */ public class Lock { public static final Byte lock = new Byte("0"); }
package com.threadTest.thread.add.state.test01; /** * Created by sky on 2017/3/23. */ public class MyThread extends Thread { public MyThread() { try { System.out.println("构造方法中的状态1: " + Thread.currentThread().getState()); Thread.sleep(1000); System.out.println("构造方法中的状态2: " + Thread.currentThread().getState()); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { try { System.out.println("run 构造方法中的状态1: " + Thread.currentThread().getState()); Thread.sleep(1000); try { synchronized (Lock.lock) { Thread.sleep(1000); Lock.lock.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("run 构造方法中的状态2: " + Thread.currentThread().getState()); } catch (InterruptedException e) { e.printStackTrace(); } } }
2、线程组
线程组作用:可以批量的管理线程或线程组对象,有效地对线程或线程组对象进行组织。
1)线程对象关联线程组:1级关联
1级关联:父对象中有子对象,但并不创建子孙对象。为了有效地对这些线程进行组织管理,通常情况下是创建一个线程组,然后将部分线程归属到该组中,对零散的线程进行有限的组织与规划。
package com.threadTest.thread.add.state.group; /** * Created by sky on 2017/3/23. */ public class ThreadA extends Thread{ @Override public void run() { try { while (!Thread.currentThread().isInterrupted()) { System.out.println("ThreadName = " + Thread.currentThread().getName()); Thread.sleep(3000); } } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.threadTest.thread.add.state.group; /** * Created by sky on 2017/3/23. */ public class ThreadB extends Thread{ @Override public void run() { try { while (!Thread.currentThread().isInterrupted()) { System.out.println("ThreadName = " + Thread.currentThread().getName()); Thread.sleep(3000); } } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.threadTest.thread.add.state.group; /** * Created by sky on 2017/3/23. */ public class Run { public static void main(String[] args) { ThreadA threadA = new ThreadA(); ThreadB threadB = new ThreadB(); ThreadGroup group = new ThreadGroup("线程组"); Thread athread = new Thread(group, threadA); Thread bthread = new Thread(group, threadB); athread.start(); bthread.start(); System.out.println("interrupt前活动的线程组: " + group.activeCount()); System.out.println("线程组的名称为: " + group.getName()); //线程中断 group.interrupt(); System.out.println("interrupt后活动的线程组: " + group.activeCount()); group.list(); } } 输出: interrupt前活动的线程组: 2 线程组的名称为: 线程组 interrupt后活动的线程组: 2 java.lang.ThreadGroup[name=线程组,maxpri=10] Thread[Thread-2,5,线程组] Thread[Thread-3,5,线程组]
2)线程对象关联线程组:多级关联
多级关联:父对象中有子对象,子对象中再创建子对象
package com.threadTest.thread.add.state.group.test02; /** * Created by sky on 2017/3/23. */ public class Run { public static void main(String[] args) { //在main组中添加一个线程组A,然后在这个A中添加线程对象Z //方法acctiveGroupCount()个acctiveCount()的值不是固定的 //是系统环境的一个快照 ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); ThreadGroup group = new ThreadGroup(mainGroup, "A"); Runnable runnable = new Runnable() { @Override public void run() { System.out.println("runMethod!"); try { Thread.sleep(10000); //线程必须在运行状态下才可以受组管理 } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread newThread = new Thread(group, runnable); newThread.setName("Z"); newThread.start();//线程必须启动后才归到A组中 ThreadGroup[] listGroup = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()]; Thread.currentThread().getThreadGroup().enumerate(listGroup); System.out.println("main 线程中有多少个子线程组: " + listGroup.length + " 名字为: " + listGroup[0].getName());; Thread[] listThread = new Thread[listGroup[0].activeCount()]; //将此listGroup[0]线程组中的每个活动线程复制到指定的数组中listThread listGroup[0].enumerate(listThread); System.out.println(listThread[0].getName()); } }
3)线程组自动归属特性
自动归属:自动归到当前线程组中
package com.threadTest.thread.add.state.group.test03; /** * Created by sky on 2017/3/23. */ public class Run { public static void main(String[] args) { //方法activeGroupCount()取得当前线程组对象中的子线程数量 //方法acctiveGroupCount()的作用是将线程中的子线程组以复制的形式拷贝到ThreadGroup[]数组对象中 System.out.println("A处线程:" + Thread.currentThread().getName() + "所属的线程组名为:" + Thread.currentThread().getThreadGroup().getName() + " " + "中有线程组数量: " + Thread.currentThread().getThreadGroup().activeGroupCount()); ThreadGroup group = new ThreadGroup("新的组");//自动加到main组中 System.out.println("B处线程:" + Thread.currentThread().getName() + " 所属的线程组名为: " + Thread.currentThread().getThreadGroup().getName() + " 中有线程组数量" + Thread.currentThread().getThreadGroup().activeGroupCount()); ThreadGroup[] threadGroups = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()]; Thread.currentThread().getThreadGroup().enumerate(threadGroups); for (int i = 0; i < threadGroups.length; i++) { System.out.println("第一个线程组名称为: " + threadGroups[i].getName()); } } }
输出:
A处线程:main所属的线程组名为:main 中有线程组数量: 0
B处线程:main 所属的线程组名为: main 中有线程组数量1
第一个线程组名称为: 新的组
4)获取根线程组
package com.threadTest.thread.add.state.group.test04; /** * Created by sky on 2017/3/23. */ public class Run { public static void main(String[] args) { System.out.println("线程:" + Thread.currentThread().getName() + " 所在的线程组名为: " + Thread.currentThread().getThreadGroup().getName()); System.out.println("main线程所在的线程组的父线程组名称是:" +Thread.currentThread().getThreadGroup().getParent() .getName()); System.out.println("main线程所在的线程组的父线程组的父线程组的名称是:" +Thread.currentThread().getThreadGroup().getParent() .getParent().getName()); } }
输出:
Exception in thread "main" java.lang.NullPointerException
at com.threadTest.thread.add.state.group.test04.Run.main(Run.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
线程:main 所在的线程组名为: main
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
main线程所在的线程组的父线程组名称是:system
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
5)线程组里加线程组
package com.threadTest.thread.add.state.group.test05; /** * Created by sky on 2017/3/23. */ public class Run { public static void main(String[] args) { System.out.println("线程组名称:" + Thread.currentThread().getThreadGroup().getName()); System.out.println("线程组中活动的线程数量:" + Thread.currentThread().getThreadGroup().activeCount()); System.out.println("线程组中线程组的数量-加之前:" + Thread.currentThread().getThreadGroup().activeGroupCount()); new ThreadGroup(Thread.currentThread().getThreadGroup(), "newGroup"); System.out.println("线程组中线程组数量-加之后:" + Thread.currentThread().getThreadGroup().activeGroupCount()); System.out.println("父线程组名称:" + Thread.currentThread().getThreadGroup().getParent().getName()); } }
输出:
线程组名称:main
线程组中活动的线程数量:2
线程组中线程组的数量-加之前:0
线程组中线程组数量-加之后:1
父线程组名称:system
6)组内的线程的批量停止
package com.threadTest.thread.add.state.group.test06; /** * Created by sky on 2017/3/23. */ public class MyThread extends Thread{ public MyThread(ThreadGroup group, String name){ super(group, name); } @Override public void run() { System.out.println("ThreadName=" + Thread.currentThread() .getName() + "准备开始死循环了:)"); while (!this.isInterrupted()) { } System.out.println("ThreadName=" + Thread.currentThread().getName() +"结束了:)"); } }
package com.threadTest.thread.add.state.group.test06; /** * Created by sky on 2017/3/23. */ public class Run { public static void main(String[] args) { try { ThreadGroup group = new ThreadGroup("我的线程组"); for (int i = 0; i < 5; i++) { MyThread thread = new MyThread(group, "线程" + (i + 1)); thread.start(); } Thread.sleep(5000); group.interrupt(); System.out.println("调用了interrupt()方法"); } catch (InterruptedException e) { System.out.println("停了!"); e.printStackTrace(); } } } 输出: ThreadName=线程1准备开始死循环了:) ThreadName=线程2准备开始死循环了:) ThreadName=线程3准备开始死循环了:) ThreadName=线程4准备开始死循环了:) ThreadName=线程5准备开始死循环了:) 调用了interrupt()方法 ThreadName=线程1结束了:) ThreadName=线程5结束了:) ThreadName=线程4结束了:) ThreadName=线程3结束了:) ThreadName=线程2结束了:)
7)递归与非递归取得组内对象
package com.threadTest.thread.add.state.group.test07; import com.threadTest.thread.add.state.group.test06.MyThread; /** * Created by sky on 2017/3/23. */ public class Run { public static void main(String[] args) { ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); ThreadGroup groupA = new ThreadGroup(mainGroup, "A"); Runnable runnable = new Runnable() { @Override public void run() { try { System.out.println("runMethod!"); Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } }; ThreadGroup groupB = new ThreadGroup(groupA, "B"); //分配空间,但不一定全部用完 ThreadGroup[] listGroup1 = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()]; //传入true是递归取得子组及子孙组 Thread.currentThread().getThreadGroup().enumerate(listGroup1,true); for (int i = 0; i < listGroup1.length; i++) { if (null != listGroup1[i]) { System.out.println(listGroup1[i].getName()); } } ThreadGroup[] listGroup2 = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()]; //传入true是递归取得子组及子孙组 Thread.currentThread().getThreadGroup().enumerate(listGroup2,false); for (int i = 0; i < listGroup2.length; i++) { if (null != listGroup2[i]) { System.out.println(listGroup2[i].getName()); } } } }
输出:
A
B
A
原文:http://www.cnblogs.com/beaconSky/p/6606425.html