一、进程与线程的概念
- 进程:操作系统管理的一个独立的运行环境,可以看成是一个运行中的程序。
- 线程:进程中的一个执行单元,线程的执行依赖进程的资源和环境,一个进程至少包含一个线程,线程并行执行不同的任务。
- 单线程:一个进程中只存在一个线程,实际上主方法就是一个主线程。
- 多线程:一个进程中存在多个线程,目的是充分使用CPU资源。
二、创建线程的方式
1. 继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("My Thread running");
}
}
// 创建线程
MyThread p = new MyThread();
// 启动线程
p.start();
2. 实现Runnable接口
public class Task implements Runnable {
@Override
public void run() {
System.out.println("My Task running");
}
}
// 创建线程
Thread p = new Thread(new Task());
// 启动线程
p.start();
三、Thread类常用方法
1. 类方法
-
public static Thread currentThread()
获取当前正在执行的线程对象。 -
public static void sleep(long millisec)
使当前正在执行的线程休眠 millisec 毫秒,如果当前线程持有锁, 则线程休眠期间不会释放锁,调用该方法需要捕获 InterruptedException 异常。 -
public static void yield()
让出当前正在执行的线程的执行权,当前线程由运行状态进入到就绪状态。
2. 实例方法
-
public void start()
使该线程开始执行,Java 虚拟机调用该线程的 run 方法。 -
public void run()
如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。 -
public final void setName(String name)
设置线程的名称。 -
public final void setPriority(int priority)
设置线程的优先级。 -
public final void setDaemon(boolean on)
设置线程为守护线程或用户线程。 -
public final void join()
让线程等待另一个线程完成执行。如A线程run()
方法中调用B线程的join()
方法,则A线程被阻塞,直到B线程执行完为止,A才能得以继续执行。 -
public void interrupt()
中断线程,当线程处于阻塞状态时,调用该方法将抛出InterruptedException
异常。 -
public final boolean isAlive()
判断线程是否处于活动状态,活动状态是线程正在运行或准备运行的状态。 -
public long getId()
返回线程的唯一标识。
四、线程的状态
线程具有下列状态。
- 创建状态(new): 创建了线程对象。
- 就绪状态(runnable): 调用了start()方法, 等待CPU的调度。
- 运行状态(running): 执行run()方法。
- 阻塞状态(blocked): 暂时停止执行。
- 终止状态(dead): run()方法结束。
五、线程的优先级
线程优先级越高,得到的CPU资源越多,Thread
类中的3个常量预定义了优先级的值。
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
线程优先级特性:
- 继承性
比如A线程启动B线程,则B线程的优先级与A是一样的。 - 规则性
高优先级的线程总是大部分先执行完,但不代表高优先级线程全部先执行完。 - 随机性
优先级较高的线程不一定每一次都先执行完。
六、Daemon线程
在Java虚拟机中有两类线程,用户线程和Daemon
线程(守护线程),Daemon
线程的作用是为其他线程的运行提供服务,比如垃圾回收线程。Java虚拟机中用户线程都执行结束了,Daemon
线程会自动退出。使用 setDaemon()
方法可以设置一个线程为守护线程 ,setDaemon()
方法必须在start()
之前执行,否则抛出IllegalThreadStateException
异常。
Daemon线程特性
Daemon
线程依赖于创建它的线程,而用户线程则不依赖。例如在A线程中创建了一个守护线程B,当A线程执行结束后B线程也会随之消亡。在
Daemon
线程中产生的新线程也是Daemon
线程。Daemon
线程不应该去访问资源,比如读写操作或者计算逻辑,因为Daemon
线程可能会在操作完成前中断执行。