多线程基础 - 状态、创建、常用方法

线程状态

java.lang.Thread.State 里明确了线程的各个状态以及怎么进入和退出各个状态

public enum State {
        // 初始化状态,线程创建之后的状态,new Thread() 之后进入
        NEW,
        // 就绪状态,线程正在运行或等待 CPU 时间片,调用了 线程的 start() 方法进入
        RUNNABLE,
        // 阻塞状态,synchronized 代码块或方法
        BLOCKED,
        /**
         * 无限期等待状态,如果不手动唤醒就一直持续该状态
         * 当调用了不带时间的 Object.wait() 进入该状态(退出状态:Object.notify() / Object.notifyAll())
         * 当调用了不带时间的 Thread.join() 进入该状态(退出状态:加入的线程执行完毕)
         * 当调用了 LockSupport.park() 进入该状态(退出状态:给线程颁发令牌,LockSupport.unpark(thread))
         */
        WAITING,
        /**
         * 期限等待,达到条件后会自动唤醒,无需手动唤醒
         * 当调用了 Thread.sleep() 进入该状态(不管带不带时间都是期限等待,虽然不带时间会一直等,这样有点像无限期等待,但是确实进入了期限等待)
         * 当调用了带时间的 Object.wait() 进入该状态(退出状态:时间结束 / Object.notify() / Object.notifyAll())
         * 当调用了带时间的 Thread.join() 进入该状态(退出状态:时间结束 / 加入的线程执行完毕)
         * 当调用了 LockSupport.parkNanos() 进入该状态(退出状态:时间结束)
         * 当调用了 LockSupport.parkUntil() 进入该状态(退出状态:到指定时刻)
         */
        TIMED_WAITING,
        // 运行结束
        TERMINATED;
    }

创建线程

继承 Thread

class MyThread1 extends Thread{
    @Override
    public void run(){
        System.out.println("继承 Thread ...");
    }
}
public class Test1 {
    public static void main(String[] args) {
        new MyThread1().start();
    }
}

实现 Runnable

class MyThread implements Runnable{
    @Override
    public void run() {
        System.out.println("继承 Runnable ......");
    }
}
public class Test1 {
    public static void main(String[] args) {
        // 创建真实对象
        MyThread myThread = new MyThread();
        // 创建代理对象
        Thread t = new Thread(myThread);
        t.start();
    }
}
// 匿名内部类
new Thread(() -> {
    System.out.println("匿名内部类方式 ......");
}).start();

实现 Callble

// 借助线程池
class MyThread implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "hello world!";
    }
}
public class Test1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建对象
        MyThread myThread = new MyThread();
        // 创建线程, 使用线程调度服务来创建, 参数表示创建线程的数量
        ExecutorService t = Executors.newFixedThreadPool(1);
        // 执行线程
        Future<String> result = t.submit(myThread);
        // 获取线程执行结果的返回值, 将会等待线程执行结束
        String s = result.get();
        System.out.println(s);
     // 停止线程池
        t.shutdownNow();
    }
}
// 使用 FutureTask 封装
FutureTask<Integer> ft = new FutureTask<>(() -> {
    return 123 + 123;
});
new Thread(ft).start();
Integer integer = ft.get();

常用方法

方法名 作用 特点
start() 启动线程,线程进入可运行状态 不是立马执行,还需要等一个时机,等抢到 CPU 调度权就执行
join() 加入线程,等加入的线程执行结束再执行当前线程
sleep() 线程休眠,让出 CPU 执行权,等到休眠时间到了才会再次争夺 CPU 执行权,休眠期间不会再次争夺 CPU 执行权 不会释放锁
yield() 线程让步,让出 CPU 执行权,强制进入就绪状态,可能刚让出 CPU 执行权立马又获取到了 不会释放锁
wait() 线程等待,让出 CPU 执行权,notify/notifyAll 之后才会再次争夺 CPU 执行权
必须同时获取到锁和得到 CPU 执行权才会执行
会释放锁
notify()/notifyAll() 唤醒等待当前锁的线程(唤醒的线程必须拿到释放的锁才可能执行,和 wait 必须持有同一把锁) 会释放锁
setPriority(int newPriority) 设置线程优先级 范围 1-10
getPriority() 获取线程优先级
setName(String name) 设置线程名称 如果不指定, 默认 Thread-index
getName() 获取线程名称
currentThread() 静态方法, 返回当前线程
posted @ 2023-05-24 15:57  CyrusHuang  阅读(11)  评论(0编辑  收藏  举报