线程相关个人笔记总结

什么是线程和进程

进程是一个程序的实例,线程是进程中的实体,一个进程有多个线程

线程的创建方式
1.继承 Thread 类重写 run()

创建一个类继承自 Thread 类,并重写 run() 方法来定义线程执行的任务。

通过创建该类的实例并调用 start() 方法来启动线程。

复制代码
class MyThread extends Thread {
    public void run() {
        // 线程执行的任务
    }
}
// 创建线程并启动
MyThread thread = new MyThread();
thread.start();
2.实现 Runnable 接口实现 run() 方法

创建一个实现 Runnable 接口的类,并实现其 run() 方法。

创建该类的实例,然后将其传递给一个新的 Thread 实例,并调用 start() 方法启动线程。

复制代码
// 写法1:创建一个类实现 Runnable 接口实现 run() 方法
class MyRunnable implements Runnable {
    public void run() {
        // 线程执行的任务
    }
}
// 创建线程并启动
Thread thread = new Thread(new MyRunnable());
thread.start();

// 写法2:使用匿名内部类在创建 Thread 或实现 Runnable 接口
Thread thread = new Thread(new Runnable() {
    public void run() {
        // 线程执行的任务
    }
});
thread.start();

// 写法3: Lambda 表达式对匿名内部类方式进行简化
Thread thread = new Thread(() -> {
    // 线程执行的任务
});
thread.start();
3.使用 Callable 和 Future:

创建一个实现 Callable 接口的类,实现 call() 方法。

使用 ExecutorService 提交 Callable 任务,返回一个 Future 对象,通过 Future 获取线程执行的结果。

复制代码
class MyCallable implements Callable<String> {
    public String call() {
        // 线程执行的任务
        return "Task completed!";
    }
}

// 使用 ExecutorService 创建线程并启动
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
try {
    String result = future.get();
    System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}
executor.shutdown();
线程生命周期
复制代码
 public enum State {
        // 创建:Thread 实例刚刚被创建,但尚未开始执行。
        NEW,
     
    	// 就绪:调用 start() 方法进入就绪状态,等待获取CPU时间片,
     	// 获取后进入运行状态,开始执行run() 方法中的任务。
        RUNNABLE,
     
    	// 阻塞:线程被阻塞,暂时停止执行,
     	// 一般在获取锁(synchronized,ReentrantLock)时被其他线程占用,或是等待I/O操作完成会进入阻塞
        BLOCKED,

    	// 等待:线程进入等待状态,需要被手动唤醒。
		// 调用 Object.wait()、Thread.join()、LockSupport.park() 等方法会使线程进入等待状态。
        WAITING,

    	// 超时等待:线程等待一定时间后自动唤醒。
		// 调用 Thread.sleep(timeout)、Object.wait(timeout)、Thread.join(timeout) 等方法会使线程进入超时等待状态。
        TIMED_WAITING,

        // 终止:线程的生命周期结束,如线程执行完任务,或者出现异常而结束
        TERMINATED;
    }
什么是ThreadLocal,可以用来做什么,怎么使用

ThreadLocal是线程级别的变量容器。每个线程都可以独立访问自己的 ThreadLocal 变量,线程之间互不影响。

一般可以用来传参,或是多线程下需要实现线程局部变量

复制代码
// 创建 ThreadLocal 变量:(创建类型有多种)
private static ThreadLocal<MyObject> myObjectThreadLocal = ThreadLocal.withInitial(() -> new MyObject());
ThreadLocal.withInitial(() -> 0);
ThreadLocal.withInitial("wrxfxdd");(文本)
ThreadLocal.withInitial(() -> false);
ThreadLocal.withInitial(User:new);(对象)
ThreadLocal.withInitial(HashMap::new);(集合)

// 设置线程局部变量的值
myObjectThreadLocal.set(new MyObject());
// 获取线程局部变量的值:
MyObject myObject = myObjectThreadLocal.get();
// 移除线程局部变量的值(
myObjectThreadLocal.remove();
什么是守护线程,用来做什么,怎么用

守护线程是在程序运行时在后台提供服务的线程。守护线程只有在普通线程全部结束后,jvm退出,才会终止

一般用来执行一些后台任务,如垃圾回收、内存管理等,例如,JVM 中的垃圾回收线程就是一个守护线程。但平时代码中很少用到,

复制代码
Thread daemonThread = new Thread(() -> {
    while (true) {
        // 守护线程的逻辑
    }
});
daemonThread.setDaemon(true);
daemonThread.start();
线程类的常用方法
Thread.join(),(毫秒)

join是线程实例的方法 ,调用 join() 方法的这个实例线程会被阻塞,直到线程结束或者使用重载的join(时间)方法,如果超过该时间没有结束,当前线程就会继续执行。用于可以按照一定顺序执行线程任务

Thread.sleep(毫秒);

sleep()是Thread类直接调用的方法,会让当前线程(一般是主线程)进入超时等待状态,超过该时间自动恢复就绪状态,可用于模拟耗时,或debug比如异步是否生效等

notify(); notifyAll():

notify() notifyAll() 方法都是object类的,notify():如果有多个线程处于等待中,只会随机唤醒一个处于等待状态(通过wait()方法进入等待状态)的线程。notifyAll() :唤醒所有处于等待状态的线程。

object.wait(),(毫秒);

wait() 方法是object类的,会让当前线程会释放对象的锁(即释放 synchronized 同步块的锁),并进入等待状态,直到被相同对象的object调用 notify() 或 notifyAll() 唤醒,主要用于线程间的同步和通信

复制代码
public class WaitNotifyExample {
    private final Object lock = new Object();
    private boolean flag = false;

    public void waitForFlag() throws InterruptedException {
        synchronized (lock) {
            while (!flag) {
                System.out.println("Waiting...");
                lock.wait();
            }
            System.out.println("Flag is true. Continue with the task.");
        }
    }

    public void setFlag() {
        synchronized (lock) {
            flag = true;
            lock.notifyAll();
        }
    }

    public static void main(String[] args) {
        WaitNotifyExample example = new WaitNotifyExample();

        Thread waitingThread = new Thread(() -> {
            try {
                example.waitForFlag();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        Thread notifyingThread = new Thread(() -> {
            // Simulate some work
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("Setting the flag to true.");
            example.setFlag();
        });
        waitingThread.start();
        notifyingThread.start();
    }
}
注意事项

使用 wait() 方法,线程必须通过synchronized获取对象的锁,否则运行时会抛出 IllegalMonitorStateException 异常(因为wait()方法是Object类的方法,它要求在对象的监视器(即通过synchronized关键字获取锁而ReentrantLock是juc下的实现,不是Object子类)

相关推荐
zzzzzz3101 小时前
别急着把动效组件搬进页面:从 react-bits 看 React 动效库该怎么评估
前端·react.js·开源
octopus_c3 小时前
数据结构:堆(Heap)详解
c语言·数据结构·算法
SeaDhdhdhdhdh8 小时前
MCP Server 搭建与使用指南
java·ai·agent·mcp
李姆斯8 小时前
为啥Agent在coding表现这么好,但是在别的领域就是差的不少?
前端·agent·ai编程
YH55269848 小时前
GPT‑5.6 Sol 原本支持 1M 上下文,Codex 现已放开此前限制,如何看待这次调整?
java·jvm·人工智能·gpt·算法·chatgpt
AI_小站9 小时前
刚面完百度的 Agent 开发岗,我才发现:世界就是个巨大的草台班子
java·开发语言·人工智能·spring·百度·langchain
普通网友9 小时前
Springboot中使用Elasticsearch(部署+使用+讲解 最完整)
spring boot·elasticsearch·jenkins
许彰午10 小时前
03-三种开发模式
java·架构
涟漪海洋10 小时前
创建最新的JDK25镜像,非root环境启动
java
遥感知识服务10 小时前
从局部阈值、双极化到暗地表剔除:NASA OPERA DSWx-S1全球动态水体算法拆解
大数据·人工智能·深度学习·神经网络·算法·机器学习