一、多线程

使用多线程

创建线程三种方式

优先选择使用 Runnable 接口;当需要返回值时,使用 Callable 接口;仅在测试或简单实现时才选择继承 Thread 类

方式一:继承 Thread 类

通过继承 Thread 类,重写run()方法

class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行逻辑
    }
}

// 使用
MyThread thread = new MyThread();
thread.start();

1)受单继承限制,不能再继承其他类

2)线程与任务绑定,不符合单一职责原则(Thread 负责线程管理,但在其中又增加了业务逻辑)

方式二:实现 Runnable 接口

实现 Runnable 接口,重写run()方法

class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行逻辑
    }
}

// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();
// 或使用线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(new MyRunnable());

1)可以多继承,使用更灵活

2)线程与任务分离,实现该接口只需关注业务逻辑,应用时一个对象可交于多个 Thread 类管理

3)支持 Lambda 表达式简化,能够配合线程池ExecutorService使用

方式三:实现 Callable 接口与 Future

Callable接口

实现 Callable 接口,重写call()方法

class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        // 线程执行逻辑
        return "执行结果";
    }
}

// 使用
ExecutorService executor = Executors.newFixedThreadPool(5);
Future<String> future = executor.submit(new MyCallable());
String result = future.get(); // 获取返回值

1)通过FutureFutureTask调用可以获得返回值

2)能够配合线程池ExecutorService使用

Future接口

只是接口,无法直接new出对象。

应当使用FutureTask类包装实现Callable接口的对象,用于管理线程执行和参数接收

public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

cancel() 方法用来取消任务,成功则返回 true,参数表示是否允许取消正在执行且未完成的任务

isCancelled()方法表示任务是否被取消成功

isDone()方法表示任务是否已经完成

get()方法用来获取执行结果,这个方法会产生阻塞,一直等到任务执行完毕才返回

get(long timeout, TimeUnit unit)若在指定时间内还没获取到结果,就直接返回 null

补充:Run()start()

1.必须重写run()方法:

默认run()方法不会做任何事,必须重写

2.Run()start()的区别:

run()封装线程执行代码,直接调用相当于普通的方法调用,start()会启动线程由 JVM 调用run()方法

线程控制方法

sleep()睡眠

设定毫秒数,使当前线程进入休眠状态

调用时会抛出InterruptedException异常,需要进行异常处理

try {
    Thread.sleep(2000); // 当前线程休眠2秒
} catch (InterruptedException e) {
    e.printStackTrace();
}

join()等待

等待该线程执行完,后续其他线程才能获得 CPU 执行权

Thread worker = new Thread(() -> {
    System.out.println("工作线程运行");
});
worker.start();
try {
    worker.join(); // 等待worker线程结束
} catch (InterruptedException e) {
    e.printStackTrace();
}

setDaemon()守护

将该线程标记为守护线程,后台运行,当所有其他线程(含main方法主线程)结束后该线程才会终止

需要在start()方法执行前设定为true

Thread daemon = new Thread(() -> {
    while (true) {
        System.out.println("守护线程运行");
    }
});
daemon.setDaemon(true); // 设置为守护线程
daemon.start();

yield()让步

向JVM提出建议,表示可以暂时让步,放弃部分 CPU 时间片

Thread.yield(); // 当前线程让出CPU

线程的六种状态

// Thread.State 源码
public enum State {
    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED;
}

NEW 新建

线程被创建但尚未启动,指当前还没有调用start()方法

Thread thread = new Thread(() -> {
    // 线程任务
});
// 此时线程状态为NEW

RUNABLE 可运行

线程此时等待 CPU 分配资源 or 位于 Java 虚拟机中运行

(包含了操作系统中就绪态和运行态两种状态)

thread.start();
// 启动后进入RUNNABLE状态

BLOCKED 阻塞

此时线程正在等待锁的释放以占用资源

// 线程1先获取锁
synchronized(lock) {
    // 线程2在此处被阻塞
}

WAITING 等待

无限期等待其他线程的特定操作,只能等待其他线程的唤醒

Object lock = new Object();
Thread thread = new Thread(() -> {
    synchronized(lock) {
        try {
            lock.wait();  // 进入WAITING状态
        } catch (InterruptedException e) {}
    }
});
thread.start();

TIMED_WAITING 限时等待

设置了超时时间的等待

Thread.sleep(1000);  // 睡眠1秒
lock.wait(5000);     // 等待5秒

TERMINATED 终止

线程执行完毕或异常终止

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇