一、介绍
学习Thread参考官方文档是个好习惯:
二、Thread
1、 创建线程有两种方式:
①、创建线程的时候传入Runnable对象;
private class SyncRunnable implements Runnable {
@Override
public void run() {
//执行耗时操作
}
}
②、另一种是继承Thread类,实现run()方法。
private class SyncThread extends Thread {
@Override
public void run() {
super.run();
//执行耗时操作
}
}
2、Thread方法:
run():包含线程运行时所执行的代码
start():用于启动线程
sleep()/sleep(long millis):线程休眠,交出CPU,让CPU去执行其他的任务,然后线程进入阻塞状态,sleep方法不会释放锁
yield():使当前线程交出CPU,让CPU去执行其他的任务,但不会是线程进入阻塞状态,而是重置为就绪状态,yield方法不会释放锁
join()/join(long millis)/join(long millis,int nanoseconds):等待线程终止,直白的说 就是发起该子线程的线程 只有等待该子线程运行结束才能继续往下运行
wait():交出cpu,让CPU去执行其他的任务,让线程进入阻塞状态,同时也会释放锁
interrupt()//中断线程,自stop函数过时之后,我们通过interrupt方法和isInterrupted()方法来停止正在运行的线程,注意只能中断已经处于阻塞的线程
getId():获取当前线程的ID
getName()/setName():获取和设置线程的名字
getPriority()/setPriority():获取和这是线程的优先级 一般property用1-10的整数表示,默认优先级是5,优先级最高是10,优先级高的线程被执行的机率高
setDaemon()/isDaemo():设置和判断是否是守护线程
currentThread():静态函数获取当前线程
3、Thread线程主要状态
①、 New 一旦被实例化之后就处于new状态
②、 Runnable 调用了start函数之后就处于Runnable状态
③、 Running 线程被cpu执行 调用run函数之后 就处于Running状态
④、Blocked 调用join()、sleep()、wait()使线程处于Blocked状态
⑤、Dea线程的run()方法运行完毕或被中断或被异常退出,线程将会到达Dead状态
4、线程同步
①、同步函数
private synchronized void count(){
System.out.append("同步函数");
}
②、同步代码块
private void count() {
synchronized (this) {
System.out.append("同步代码块");
}
}
5、Thread销毁
private void destroyThread() {
SyncThread syncThread = new SyncThread();
try {
if (syncThread != null && Thread.State.RUNNABLE == syncThread.getState()) {
syncThread.sleep(1000);
syncThread.interrupt();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
syncThread = null;
}
}
二、ThreadGroup 线程组
线程组表示一个线程的集合。此外,线程组也可以包含其他线程组。线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组。
允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息。
1、构造方法:
ThreadGroup(String name) // 构造一个新线程组。新线程组的父线程组是目前正在运行线程的线程组。不使用任何参数调用父线程组的 checkAccess 方法;这可能导致一个安全性异常。
ThreadGroup(ThreadGroup parent, String name) // 创建一个新线程组。新线程组的父线程组是指定的线程组。 不使用任何参数调用父线程组的 checkAccess 方法;这可能导致一个安全性异常。
ThreadGroup类中的某些方法,可以对线程组中的线程产生作用。例如,setMaxPriority()方法可以设定线程组中的所有线程拥有最大的优先权。
所有线程都隶属于一个线程组。那可以是一个默认线程组(不指定group),亦可是一个创建线程时明确指定的组。在创建之初,线程被限制到一个组里,而且不能改变到一个不同的组。每个应用都至少有一个线程从属于系统线程组。若创建多个线程而不指定一个组,它们就会自动归属于系统线程组。
线程组也必须从属于其他线程组。必须在构建器里指定新线程组从属于哪个线程组。若在创建一个线程组的时候没有指定它的归属,则同样会自动成为系统线程组的一名属下。因此,一个应用程序中的所有线程组最终都会将系统线程组作为自己的“父”。
我们在给线程池(ThreadPoolExecutor)提交任务的时候可以通过execute(Runnable command)来将一个线程任务加入到该线程池,但通过线程组来对线程池中的线层任务分组不可行。
2、部分方法:
int activeCount() 返回此线程组中活动线程的估计数。
int activeGroupCount() 返回此线程组中活动线程组的估计数。
boolean allowThreadSuspension(boolean b) 已过时。 此调用的定义取决于 suspend(),它被废弃了。更进一步地说,此调用的行为从不被指定。
void checkAccess() 确定当前运行的线程是否有权修改此线程组。
void destroy() 销毁此线程组及其所有子组。
int enumerate(Thread[] list) 把此线程组及其子组中的所有活动线程复制到指定数组中。
int enumerate(Thread[] list, boolean recurse) 把此线程组中的所有活动线程复制到指定数组中。
int enumerate(ThreadGroup[] list) 把对此线程组中的所有活动子组的引用复制到指定数组中。
int enumerate(ThreadGroup[] list, boolean recurse) 把对此线程组中的所有活动子组的引用复制到指定数组中。
int getMaxPriority() 返回此线程组的最高优先级。
String getName() 返回此线程组的名称。
ThreadGroup getParent() 返回此线程组的父线程组。
void interrupt() 中断此线程组中的所有线程。
boolean isDaemon() 测试此线程组是否为一个后台程序线程组。
boolean isDestroyed() 测试此线程组是否已经被销毁。
void list() 将有关此线程组的信息打印到标准输出。
boolean parentOf(ThreadGroup g) 测试此线程组是否为线程组参数或其祖先线程组之一。
void resume() 已过时。 此方法只用于联合 Thread.suspend 和 ThreadGroup.suspend 时,因为它们所固有的容易导致死锁的特性,所以两者都已废弃。有关详细信息,请参阅 Thread.suspend()。
void setDaemon(boolean daemon) 更改此线程组的后台程序状态。
void setMaxPriority(int pri) 设置线程组的最高优先级。
void stop() 已过时。 此方法具有固有的不安全性。有关详细信息,请参阅 Thread.stop()。
void suspend() 已过时。 此方法容易导致死锁。有关详细信息,请参阅 Thread.suspend()。
String toString() 返回此线程组的字符串表示形式。
void uncaughtException(Thread t, Throwable e) 当此线程组中的线程因为一个未捕获的异常而停止,并且线程没有安装特定 Thread.UncaughtExceptionHandler 时,由 Java Virtual Machine 调用此方法。