Java线程与并发编程实践----额外的线程能力

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java线程与并发编程实践----额外的线程能力相关的知识,希望对你有一定的参考价值。

一、线程组

  技术分享图片

    这是Thread类的某些构造方法,可以看到有一个参数为ThreadGroup类,该类就是线程组,

JDK中是这样描述的:

线程组表示一个线程的集合。此外,线程组也可以包含其他线程组。线程组构成一棵树,

在树中,除了初始线程组外,每个线程组都有一个父线程组。允许线程访问有关自己的

线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息。 

    使用ThreadGroup对象,你可以对线程组中的所有线程对象进行操作,线程组简化

了多条线程的管理工作。

    尽管线程组看上去非常有用但是碍于下列原因,我们万万不能使用它:

  •     ThreadGroup中最有用的方法就是void suspend()、void resume()以及void stop()

但这些方法都已经被废弃了,他们很容易诱发死锁等问题。

  • ThreadGroup是非线程安全的。

但是ThreadGroup在处理线程执行过程中崔产生的异常方面做出的贡献,我们还是应该对他有所了解。

public class Test {
	
	public static void main(String[] args) {
		Runnable r = new Runnable() {
			
			@Override
			public void run() {
				int a = 1 / 0;
			}
		};
		Thread th = new Thread(r);
		th.start();
	}
}

运行结果:

Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
	at Test$1.run(Test.java:10)
	at java.lang.Thread.run(Thread.java:745)

上面是当一个异常在线程的run()方法内被抛出时的处理结果。那么问题来了,线程中的这个异常

是如何处理的呢,流程是这样的,当run()方法中抛出异常时,JVM会获取一个Thread.UncaughtExceptionHandler

的实例,该实例有Thread的setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)方法

设置,当找到这个Handler时,线程执行他的void uncughtException();进行异常处理打印抛出异常。

那么Thread.UncaughtExceptionHandler又是从哪里来的呢?

技术分享图片

如上他是被Thread类所封闭的一个接口,所谓封闭类相当于如下:

public class Test {
	
	public interface myInterface{
		
	}
}

但是我们好像并没有进行setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)这一步操作

那这个异常是如何处理的呢?其实当我们没有设置异常处理程序的时候,他会自动启动默认

的异常处理流程,源代码如下:

public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(
                new RuntimePermission("setDefaultUncaughtExceptionHandler")
                    );
        }

         defaultUncaughtExceptionHandler = eh;
     }

该方法是设置默认的处理方式,就是刚才程序运行所打印出来的那种形式。下面我们自己来设定异常处理:

import java.lang.Thread.UncaughtExceptionHandler;

public class Test {
	
	public static void main(String[] args) {
		Runnable r = new Runnable() {
			
			@Override
			public void run() {
				int a = 1 / 0;
			}
		};
		Thread.UncaughtExceptionHandler tu = new Thread.UncaughtExceptionHandler() {
			
			@Override
			public void uncaughtException(Thread t, Throwable e) {
				System.out.println("自定义异常处理。。。" + e + "该线程为" + t);
			}
		};
		Thread th = new Thread(r);
		th.setUncaughtExceptionHandler(tu);
		th.start();
	}
}

运行结果:

自定义异常处理。。。java.lang.ArithmeticException: / by zero该线程为Thread[Thread-0,5,main]

但是搞了半天好像异常处理和ThreadGroup没什么关系,其实不然,观察下图:

技术分享图片

ThreadGroup实现了Thread.UncaughtExceptionHandler,因此

当我们没有调用setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)时,

JVM会自动找到线程对应的ThreadGroup对象,找到他重写了的uncaughtException(Thread t,Throwable e)

方法进行异常处理,倘若该ThreadGroup对象没有重写此方法,他会找到它父类的方法进行执行。

二、线程局部变量

参见以前的博客:http://blog.51cto.com/12222886/1940714

三、定时器框架

    有的任务的执行需要我们定义一个时间,并非立即执行,有的任务可能

定时只执行一次,而有的会定时重复执行,定时器框架可以解决这些问题。

Java.Util.Timer和Java.Util.TimeTasks

具体不在赘述,可参见JDK文档

以上是关于Java线程与并发编程实践----额外的线程能力的主要内容,如果未能解决你的问题,请参考以下文章

Java线程与并发编程实践----同步

Java线程与并发编程实践----并发工具类与Executor框架

Java线程与并发编程实践----同步器(Phaser)

java线程与并发编程实践

Java线程与并发编程实践----等待通知(生产者消费者问题)线程

Java线程与并发编程实践----锁框架