Thread是用于创建线程的类,实现了Runnable接口,会在内部创建线程处理run()方法的逻辑
Runnable是函数式接口,内部只有一个抽象run()方法,可传递Lambda表达式,将任务和线程的操作分离开来,实现代码的解耦合,其源码为
public interface Runnable {
public abstract void run();
}
继承Thread将业务代码放在重写的run()方法中
public class MyThread extends Thread{
@Override
public void run() {
}
}
使用时调用start()方法
Thread myThread = new MyThread();
myThread.start();
当线程只需要使用一次时,可用匿名对象
new Thread(){
@Override
public void run() {
}
}.start();
继承的Thread需要有带Runnable参数的构造函数
public class MyThread extends Thread{
public MyThread(@Nullable Runnable target) {
super(target);
}
}
实现Runnable
public class MyRunnable implements Runnable {
@Override
public void run() {
}
}
调用时
Runnable myRunnable = new MyRunnable();
Thread myThread = new MyThread(myRunnable);
myThread.start();
继承的Thread需要有带Runnable参数的构造函数
public class MyThread extends Thread{
public MyThread(@Nullable Runnable target) {
super(target);
}
}
调用时
Thread myThread = new MyThread(new Runnable() {
@Override
public void run() {
}
});
myThread.start();
实现Runnable
public class MyRunnable implements Runnable {
@Override
public void run() {
}
}
调用时
MyRunnable myRunnable = new MyRunnable();
new Thread(myRunnable).start();
在大多数情况下,Runnable和Thread都是只用一次,此时两者都可采用匿名方式
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
推荐使用引入Runnable的4种方式
run()方法:执行同一线程中的任务,而不会启动新线程
start()方法:创建一个执行run()方法的新线程
sleep()方法:暂停当前线程的活动
线程终止的三个条件:
线程的interrupt()方法可中断线程,调用后将置位线程中断状态
Thread.currentThread().interrupt();
而清空线程中断状态则调用interrupted(),其返回值为原来中断状态
Thread.interrupted();
判断中断状态调用isInterrupted(),如果线程被阻塞,则无法检测中断状态,此时调用会出现Interrupted Exception,中断不等于终止,线程可以选择如何响应中断
while (!Thread.currentThread().isInterrupted()){
}
可通过setPriority()设置[1,10]的优先级,默认为5(子线程会继承父线程优先级)
Thread.currentThread().setPriority(10);
不要设置过多高优先级的线程,其可能会导致低优先级的线程永远无法执行
可通过setDaemon()将当前线程转为守护线程,守护线程为其他线程服务,当只剩下守护线程时,会退出程序
Thread.currentThread().setDaemon(true);
不要用守护线程去访问固定资源(文件、数据库),因为其会在任意时刻中断
当线程抛出异常且未捕获时,线程会终止,此时异常会传递到一个未捕获异常处理器,可对其指定
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
}
});
还可对所有线程指定未捕获异常处理器
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
}
});
独立线程的未捕获异常处理器默认未该线程的ThreadGroup对象