java线程组ThreadGroup

一、线程组合线程池的异同:

线程组:
线程组存在的意义,首要原因是安全。
java默认创建的线程都是属于系统线程组,而同一个线程组的线程是可以相互修改对方的数据的。
但如果在不同的线程组中,那么就不能“跨线程组”修改数据,可以从一定程度上保证数据安全。

线程池:
线程池存在的意义,首要作用是效率。
线程的创建和结束都需要耗费一定的系统时间(特别是创建),不停创建和删除线程会浪费大量的时间。所以,在创建出一条线程并使其在执行完任务后不结束,而是使其进入休眠状态,在需要用时再唤醒,那么 就可以节省一定的时间。
如果这样的线程比较多,那么就可以使用线程池来进行管理。保证效率。

线程组和线程池共有的特点:
1,都是管理一定数量的线程
2,都可以对线程进行控制---包括休眠,唤醒,结束,创建,中断(暂停)--但并不一定包含全部这些操作。

二、总结:

在Java中每个线程都属于某个线程组(ThreadGroup)。例如,如果在main()中产生一个线程,则这个线程属于main线程组管理的一员,您可以使用下面的指令来获得目前线程所属的线程组名称:

Thread.currentThread().getThreadGroup().getName();

一个线程产生时,都会被归入某个线程组,视线程是在哪个线程组中产生而定。如果没有指定,则归入产生该子线程的线程组中。您也可以自行指定线程组,线程一旦归入某个组,就无法更换组。        java.lang.ThreadGroup类正如其名,可以统一管理整个线程组中的线程,您可以使用以下方式来产生线程组,而且一并指定其线程组:

ThreadGroup threadGroup1 = new ThreadGroup("group1");
ThreadGroup threadGroup2 = new ThreadGroup("group2");
Thread thread1 = new Thread(threadGroup1, "group1's member");
Thread thread2 = new Thread(threadGroup2, "group2's member");

     

ThreadGroup中的某些方法,可以对所有的线程产生作用,例如interrupt()方法可以interrupt线程组中所有的线 程,setMaxPriority()方法可以设置线程组中线程所能拥有的最高优先权(本来就拥有更高优先权的线程不受影响)。
    如果想要一次获得线程组中所有的线程来进行某种操作,可以使用enumerate()方法,例如:

Thread[] threads = new Thread[threadGroup1.activeCount()];
threadGroup1.enumerate(threads);

     ThreadGroup中有一个uncaughtException()方法。当线程组中某个线程发生Unchecked exception异常时,由执行环境调用此方法进行相关处理,如果有必要,可以重新定义此方法,请看下面的示例。

package onlyfun.caterpillar;

 

public class ThreadGroupDemo {

    public static void main(String[] args) {

ThreadGroup threadGroup1 =

// 这是匿名类写法

new ThreadGroup("group1") {

    // 继承ThreadGroup并重新定义以下方法

    // 在线程成员抛出unchecked exception

    // 会执行此方法

    public void uncaughtException(Thread t, Throwable e) {

System.out.println(t.getName() + ": " + e.getMessage());

    }

};

 

// 这是匿名类写法

Thread thread1 =

// 这个线程是threadGroup1的一员

new Thread(threadGroup1, new Runnable() {

    public void run() {

// 抛出unchecked异常

throw new RuntimeException("测试异常");

    }

});

 

thread1.start();

    }

}

  

在uncaughtException()方法的参数中,第一个参数可以获得发生异常的线程实例,而第二个参数可以获得异常对象,范例中显示了线程的名称及异常信息。

三、附上示例代码:

public class TestThreadGroup {

	static class MyThread extends Thread {

		@Override
		public void run() {
			ThreadGroup currentThreadGroup = Thread.currentThread()
					.getThreadGroup();
			System.out.println(currentThreadGroup.getName() + ","
					+ currentThreadGroup.getParent().getName());

			System.out.println(getName() + "," + getId() + ","
					+ Thread.currentThread().getName());

			System.out.println(Thread.currentThread().getState());

			// if(Thread.currentThread().getState()==Thread.State.RUNNABLE)
			{

			}
			// super.run();
		}
	}

	public static void main(String[] args) throws Exception {

		new MyThread().start();
		// ThreadGroup currentThreadGroup=Thread.currentThread().getThreadGroup();
		// System.out.println(currentThreadGroup.getName()+","+currentThreadGroup.getParent().getName());
		 test001();
		ThreadGroup sys = Thread.currentThread().getThreadGroup().getParent();
		// sys.list(); // (1)
		// System.out.println(JSON.toJSONString(sys));
		//test002();

	}

	private static void test002() throws InterruptedException {
		// 创建线程组对象。
		ThreadGroup tg = new ThreadGroup("group 1");

		// 向线程组中加入10个线程。
		for (int i = 0; i < 10; i++) {
			Thread th = new Thread(tg, new TestRunnable(), "thread_" + i);
			th.start();
		}

		// 等待2秒。
		Thread.sleep(2000);
		// 中断所有线程。
		tg.interrupt();
		// 输出
		System.out.println(tg.activeCount());
	}

	private static class TestRunnable implements Runnable {
		@Override
		public void run() {
			String thName = Thread.currentThread().getName();
			System.out.printf("'%s' started. \n", thName);
			while (!Thread.currentThread().isInterrupted()) {
			}
			System.out.printf("'%s' ended. \n", thName);
		}
	}

	// 通过ThreadGroup管理线程
	private static void test001() {
		// ThreadGroup group=new ThreadGroup("group");
		// Thread thread=new Thread(group,"the first thread of group");

		// 这是匿名类写法
		ThreadGroup threadGroup1 = new ThreadGroup("group1") {
			// 继承ThreadGroup并重新定义以下方法
			// 在线程成员抛出unchecked exception
			// 会执行此方法
			public void uncaughtException(Thread t, Throwable e) {

				System.out.println(t.getName() + ": " + e.getMessage());
			}
		};

		// 这是匿名类写法 // 这个线程是threadGroup1的一员
		Thread thread1 = new Thread(threadGroup1, new Runnable() {
			public void run() {
				// 抛出unchecked异常
				throw new RuntimeException("测试异常 fuck");
			}
		});
		thread1.start();
	}

}
// How threads can access other threads in a parent thread group
public class TestAccess {
	
	public static void main(String[] args) {
		ThreadGroup x = new ThreadGroup("x"),
		y = new ThreadGroup(x, "y"), 
		z = new ThreadGroup(y, "z");
		
		Thread one = new TestThread1(x, "one"), 
		two = new TestThread2(z, "two");
	}
}

class TestThread1 extends Thread {
	private int i;

	TestThread1(ThreadGroup g, String name) {
		super(g, name);
	}

	void f() {
		i++; // modify this thread
		System.out.println(getName() + " f()");
	}
}

//继承线程1
class TestThread2 extends TestThread1 {
	
	TestThread2(ThreadGroup g, String name) {
		super(g, name);
		start();
	}

	
	public void run() {
		//使用ThreadGroup  父线程可以控制子线程
		ThreadGroup g = getThreadGroup().getParent().getParent();
		//打印线程组信息
		g.list();
		
		
		Thread[] gAll = new Thread[g.activeCount()];//活动子线程数量
		//获取活动的子线程
		g.enumerate(gAll);
		for (int i = 0; i < gAll.length; i++) {
			gAll[i].setPriority(Thread.MIN_PRIORITY);
			((TestThread1) gAll[i]).f();
		}
		//打印线程组信息
		g.list();
	}
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值