
Java 多线程
Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。
创建
实现 Runnable 接口
创建一个线程,最简单的方法是创建一个实现 Runnable 接口的类。
为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下:
public void run()
在创建一个实现 Runnable 接口的类之后,你可以在类中实例化一个线程对象。
Thread 定义了几个构造方法,下面的这个是我们经常使用的:
Thread(Runnable threadOb, String threadName);
threadOb
是一个实现 Runnable
接口的类的实例,并且 threadName
指定新线程的名字。
新线程创建之后,你调用它的 start()
方法它才会运行。
void start();
继承 Thread 类
创建一个线程的第二种方法是创建一个新的类,该类继承 Thread
类,然后创建一个该类的实例。
继承类必须重写 run()
方法,该方法是新线程的入口点。它也必须调用 start()
方法才能执行。
该方法尽管被列为一种多线程实现方式,但是本质上也是实现了 Runnable
接口的一个实例。
Thread 方法
public void start() // 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
public void run() // 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
public final void setName(String name) // 改变线程名称,使之与参数 name 相同。
public final void setPriority(int priority) // 更改线程的优先级。
public final void setDaemon(boolean on) // 将该线程标记为守护线程或用户线程。
public final void join(long millisec) // 等待该线程终止的时间最长为 millis 毫秒。
public void interrupt() // 中断线程。
public final boolean isAlive() // 测试线程是否处于活动状态。
public static void yield() // 暂停当前正在执行的线程对象,并执行其他线程。
public static void sleep(long millisec) // 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
public static boolean holdsLock(Object x) // 当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。
public static Thread currentThread() // 返回对当前正在执行的线程对象的引用。
public static void dumpStack() // 将当前线程的堆栈跟踪打印至标准错误流。
通过 Callable 和 Future 创建线程。
- 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
- 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
- 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
- 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
创建线程的三种方式的对比
- 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。
- 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。