1、创建多线程的两种方式
- 通过直接继承thread类,然后覆盖run()方法。
- 构建一个实现Runnable接口的类, 然后创建一个thread类对象并传递Runnable对象作为构造参数
2、线程(Thread)一些常用属性、方法
- ID: 每个线程的独特标识。
- Name: 线程的名称。
- Priority: 线程对象的优先级。优先级别在1-10之间,1是最低级,10是最高级。不建议改变它们的优先级,但是你想的话也是可以的。
- Status: 线程的状态。在Java中,线程只能有这6种中的一种状态: new, runnable, blocked, waiting, time waiting, 或 terminated.
- Sleep:当你调用sleep()方法, Thread 离开CPU并在一段时间内停止运行。在这段时间内,它是不消耗CPU时间的,使用可以执行其他任务。
- Join:Thread 类的join() 方法。当前线程调用某个线程的这个方法时,它会暂停当前线程,直到被调用线程执行完成。
- ThreadGroup:ThreadGroup 对象可以由 Thread 对象组成和由另外的 ThreadGroup 对象组成,生成线程树结构。ThreadGroup 类储存线程对象和其他有关联的 ThreadGroup 对象,所以它可以访问他们的所有信息 (例如,状态) 和全部成员的操作表现 (例如,中断)。
3、线程的中断
Thread 类还有一个boolean类型的属性来表明线程是否被中断。当你调用线程的interrupt() 方法,就代表你把这个属性设置为 true。 而isInterrupted() 方法仅返回属性值。
Thread 类还有其他可以检查线程是否被中断的方法。例如,这个静态方法interrupted()能检查正在运行的线程是否被中断。
isInterrupted()和interrupted() 方法有着很重要的区别。
第一个不会改变interrupted属性值,但是第二个会设置成false。
interrupted() 方法是一个静态方法,建议使用isInterrupted()方法。
PS:线程是可以忽略中断指令的
中断线程最好的,最受推荐的方式是,使用共享变量(shared variable)发出信号,告诉线程必须停止正在运行的任务。线程必须周期性的核查这一变量(尤其在冗余操作期间),然后有秩序地中止任务。
4、异常检查
Java里有2种异常:
- 检查异常(Checked exceptions): 这些异常必须强制捕获它们或在一个方法里的throws子句中。 例如, IOException 或者ClassNotFoundException。
- 未检查异常(Unchecked exceptions): 这些异常不用强制捕获它们。例如, NumberFormatException。
在一个线程 对象的 run() 方法里抛出一个检查异常,我们必须捕获并处理他们。因为 run() 方法不接受 throws 子句。当一个非检查异常被抛出,默认的行为是在控制台写下stack trace并退出程序。
当在一个线程里抛出一个异常,但是这个异常没有被捕获(这肯定是非检查异常), JVM 检查线程的相关方法是否有设置一个未捕捉异常的处理者 。如果有,JVM 使用Thread 对象和 Exception 作为参数调用此方法 。
Thread 类有其他相关方法可以处理未捕获的异常。静态方法setDefaultUncaughtExceptionHandler() 为应用里的所有线程对象建立异常 handler 。
当一个未捕捉的异常在线程里被抛出,JVM会寻找此异常的3种可能潜在的处理者(handler)。
首先, 它寻找这个未捕捉的线程对象的异常handle,如我们在在这个指南中学习的。如果这个handle 不存在,那么JVM会在线程对象的ThreadGroup里寻找非捕捉异常的handler
5、本地线程变量
ThreadLocal存放的值是线程内共享的,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递,这样处理后,能够优雅的解决一些实际问题,比如
hibernate中的OpenSessionInView,就是使用ThreadLocal保存Session对象
6、线程工厂
工厂模式是最有用的设计模式。它是一个创造模式,还有它的目的是创建一个或几个类的对象的对象。然后,当我们想创建这些类的对象时,我们使用工厂来代替new操作。
有了这个工厂,我们有这些优势来集中创建对象们:
- 更简单的改变了类的对象创建或者说创建这些对象的方式。
- 更简单的为了限制的资源限制了对象的创建。 例如, 我们只new一个此类型的对象。
- 更简单的生成创建对象的统计数据。
Java提供一个接口, ThreadFactory 接口实现一个线程对象工厂。 并发 API 使用线程工厂来创建线程的一些基本优势。
ThreadFactory 接口只有一个方法是 newThread。它接收 Runnable 对象作为参数并返回一个 Thread 对象。当你实现一个 ThreadFactory 接口,你必须实现此接口并覆盖这个方法。最基本的 ThreadFactory只有一行。
return new Thread(r);
你可以加一些变量来提升这个实现:
- 在这个例子中创建自定义线程,名字使用特别形式或者继承Java Thread类来创建自己的Thread类。
- 保存线程创建数据,如之前的例子。
- 限制线程创建个数。
- 验证线程的创建。
- 和你能想到的任何东西。
使用工厂设计模式是很好的练习,但是,如果你实现一个 ThreadFactory 接口来集中创建线程,那么你必须再检查代码确保使用的线程都是用这个工厂创建的。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于