java 并发编程-基础篇

java 创建线程的三种方法

直接使用 Thread

// 创建线程对象
Thread t = new Thread() {
    public void run() {
        // 要执行的任务
    }
};
// 启动线程
t.start();

Runable 配合 Thread

把线程和任务分开。

Runnable runnable = new Runnable() {
    public void run(){
        // 要执行的任务
    }
};
// 创建线程对象
Thread t = new Thread( runnable );
// 启动线程
t.start();

java8 以后,可以使用 lambda 表达式简化代码。

// 创建任务对象
Runnable task2 = () -> log.debug("hello");
// 参数1 是任务对象; 参数2 是线程名字,推荐
Thread t2 = new Thread(task2, "t2");
t2.start();

这里能够使用 lambda 的原因是:

对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个 lambda 表达式。这种接口称为函数式接口。

而 Runnable 就是一个函数式接口,其内部只有一个 run 方法。

FutureTask 配合 Thread

FutureTask 能够接收 Callable 类型的参数,用来处理有返回结果的情况。

// 创建任务对象
FutureTask<Integer> task3 = new FutureTask<>(() -> {
    log.debug("hello");
    return 100;
});
// 参数1 是任务对象; 参数2 是线程名字,推荐
new Thread(task3, "t3").start();
// 主线程阻塞,同步等待 task 执行完毕的结果
Integer result = task3.get();
log.debug("结果是:{}", result);

需要注意的是,这里调用 task3.get() 获取返回值时,子线程执行完毕之前,主线程是阻塞的。(这里的作用类似于 join 方法)

常见方法

  • start():启动新线程。但 cup 的时间片不一定立刻分给它。
  • run():新线程启动后自己调用的方法。如果传递了 Runnable 对象,则会调用 Runnable 中的 run 方法。
  • join():等待线程运行结束。
  • join(long n):最多等待 n 毫秒。
  • getId:获取线程 id。
  • getName():获取线程名称。
  • setName():设置线程名称。
  • interrupt():打断线程。如果被打断线程正在 sleep、wait、join,则会抛出异常并清除打断标记(打断标记仍为 false),否则,设置打断标记(打断标记为 true)。
  • sleep(long n):静态方法,当前线程休眠 n 毫秒。此时 cpu 时间片让给其它线程。
  • yield():静态方法,让出 cpu 使用权。

start 与 run

调用 run 方法时,子线程内的操作仍在 主线程执行。

调用 start 方法时,子线程内的操作才是在其它线程执行。

sleep 与 yield

sleep 方法使线程从运行态进入阻塞态,且 sleep 结束后 cpu 不一定会立刻执行该线程。

yield 方法使线程从运行态进入就绪态,主动让出 cpu。

join 方法

主要用于线程同步。

一个线程里调用另一个线程的 join 方法,就会等待 另一个线程结束才会继续执行。

interrupt 方法

打断 sleep、yield、join 状态的线程时,被打断的线程会抛出异常,并且清除打断状态。即 interrupted 参数仍为 false。

但打断正常状态的线程时,interrupted 为 true(可以用于判断是否需要料理后事)。

守护线程

在所有非守护线程都结束时,守护线程无论是否执行完,都会结束。

通过 setDaemon(true) 来设置守护线程。

posted @   临安剑客  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示