三种创建

继承 Thread 类

简单但是有java单继承的局限性

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程执行:" + Thread.currentThread().getName());
    }
}
public class Test {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        t1.start();
        t2.start();
    }
}

实现 Runnable 接口

不能接收返回值

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程执行:" + Thread.currentThread().getName());
    }
}
public class Test {
    public static void main(String[] args) {
        MyRunnable task = new MyRunnable();
        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        t1.start();
        t2.start();
    }
}

Callable + FutureTask

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println("线程执行:" + Thread.currentThread().getName());
        return 100;
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        MyCallable callable = new MyCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        Thread t1 = new Thread(futureTask);
        t1.start();
        Integer result = futureTask.get();
        System.out.println("返回结果:" + result);
    }
}

线程状态

1️⃣ NEW(新建)

线程刚创建,还没启动
Thread t = new Thread();

2️⃣ RUNNABLE(可运行)

调用了 start() 之后
t.start();

Java 里的 RUNNABLE 包含两种:
正在运行(Running)
等待 CPU(Ready)

3️⃣ BLOCKED(阻塞)

等待获取锁

4️⃣ WAITING(无限等待)

线程主动等待,直到被唤醒

常见方法:
Object.wait()
Thread.join()
LockSupport.park()

特点:
必须别人叫醒(notify / unpark)

5️⃣ TIMED_WAITING(超时等待)

等待一段时间,时间到了自动恢复

常见方法:
Thread.sleep(1000)
wait(1000)
join(1000)

6️⃣ TERMINATED(终止)

线程执行完毕

方法

start

t.start(); 启动线程

sleep

sleep是 Java 中 Thread 类的一个静态方法:Thread.sleep(long millis)
不释放锁!!!

join

实例方法。
一个线程里加入另一个线程,自身线程先停止运行。

t.join();//无限等待
t.join(1000); // 最多等1秒

wait和notify

Object类中有三个方法: wait()、notify()、notifyAll

三个核心点:
任何对象中都一定有这三个方法
只有对象作为锁对象的时候,才可以调用
只有在同步的代码块中,才可以调用
其他情况下,调用一个对象的这三个方法,都会报错!

obj.wait(); 当前线程从Runnable变成Waiting
obj.notify();随机唤醒一个等待obj锁对象的线程,从Waiting变成Runnable
obj.notifyAll();所以等待obj锁对象的线程,从Waiting变成Blocked,随机一个再变成Runnable
obj.wait(1000); 当前线程从Runnable变成Timed_Waiting,时间到了后,变成blocked

interrupt

把false改成true

线程类Thread中的 interrupt 方法:非静态

线程A中,调用了线程B的 interrupt 方法,而此时线程B处于阻塞状态,那么此时 sleep 方法或者 join 方法 或者 wait 方法就会抛出被打断的异常

interrupt 方法是通过改变线程对象中的一个标识的值(true|false),来达到打断阻塞状态的效果。

一个线程在阻塞状态下,会时刻监测这个标识的值是不是true,如果一旦发现这个值变为true,那么就抛出异常结束阻塞状态,并再把这个值改为false。

interrupt 方法中其实是调用了 interrupt0 这个本地方法

如果变成了true 再sleep,会立即抛异常。

try {
    Thread.sleep(10000);
} catch (InterruptedException e) {
    //此时:线程变阻塞或可运行,标识符变false。
    //中断标志重新变成 true
    Thread.currentThread().interrupt(); 
}

Thread.sleep(10000); // 再次 sleep,如果上面中断标志重新变成 true,这时就会抛异常

//Thread.currentThread().interrupt()目的是:
//catch InterruptedException 后,恢复中断标志的目的,是把这次中断“传递”给上层或后续逻辑,让线程能够正确响应,而不是吞掉它。

isInterrupted

返回这个“打断标识”值

线程类Thread中的 isInterrupted 方法:非静态

这个非静态方法,只是返回这个“打断标识”值,并且不会对这个值进行清除(true-

false),因为所传参数ClearInterrupted的值为false

interrupted

返回这个“打断标识”值,并true->false

线程类Thread中的 interrupted 方法:静态

这个静态方法,返回这个“打断标识”值,并且会对这个值进行清除(true->false),因为所传参数ClearInterrupted的值为true

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐