创建多线程的4种方式&&Thread类中的常用方法

本文介绍了多线程的四种创建方式,包括继承Thread类、实现Runnable接口、实现Callable接口和使用线程池。对比了前两种方式的优缺点,还阐述了Thread类的常用方法、线程优先级的设置与获取,以及线程通信和线程分类等知识。

多线程的创建方式一:继承于Thread类
1. 创建一个继承于Thread类的子类
2. 重写Thread类的run() --> 将此线程执行的操作声明在run()中
3. 创建Thread类的子类的对象
4. 通过此对象调用start()

说明两个问题:
问题一:我们启动一个线程,必须调用start(),不能调用run()的方式启动线程。
问题二:如果再启动一个线程,必须重新创建一个Thread子类的对象,调用此对象的start().
多线程的创建方式二:实现Runnable接口
1. 创建一个实现了Runnable接口的类
2. 实现类去实现Runnable中的抽象方法:run()
3. 创建实现类的对象
4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
5. 通过Thread类的对象调用start()

两种方式的对比:
开发中:优先选择:实现Runnable接口的方式
原因:1. 实现的方式没类的单继承性的局限性
2. 实现的方式更适合来处理多个线程共享数据的情况。
联系:public class Thread implements Runnable
相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run()中。
目前两种方式,要想启动线程,都是调用的Thread类中的start()。
多线程的创建方式三:实现Callable接口 — JDK 5.0新增
1. 创建一个实现Callable的实现类
2. 实现call方法,将此线程需要执行的操作声明在call()中
3. 创建Callable接口实现类的对象
4. 将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
5. 将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
6. 获取Callable中call方法的返回值

多线程创建的方式四:使用线程池 — JDK 5.0新增
1. 提供指定线程数量的线程池
2. 执行指定的线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象
3. 关闭连接池

Thread类中的常用方法
1. start():启动当前线程;调用当前线程的run()
2. run(): 通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
3. currentThread():静态方法,返回执行当前代码的线程
4. getName():获取当前线程的名字
5. setName():设置当前线程的名字
6. yield():释放当前cpu的执行权
7. join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才结束阻塞状态。
8. stop():已过时。当执行此方法时,强制结束当前线程。
9. sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒。在指定的millitime毫秒时间内,当前线程是阻塞状态。
10. isAlive():判断当前线程是否存活

线程的优先级:
* MAX_PRIORITY:10
* MIN _PRIORITY:1
* NORM_PRIORITY:5 -->默认优先级

如何获取和设置当前线程的优先级:
getPriority():获取线程的优先级
setPriority(int p):设置线程的优先级
说明:高优先级的线程要抢占低优先级线程cpu的执行权。但是只是从概率上讲,高优先级的线程高概率的情况下被执行。并不意味着只当高优先级的线程执行完以后,低优先级的线程才执行。
线程通信:wait() / notify() / notifyAll() :此三个方法定义在Object类中的。
补充:线程的分类
一种是守护线程,一种是用户线程。

<think>好的,用户想了解实际开发中创建多线程常用方法,特别是常见的方式和实际项目中的使用示例。我需要先整理一下常见的多线程实现方式,并结合引用中的信息给出回答。 首先,根据引用[2]和引用[4],Java中多线程的实现主要有继承Thread和实现Runnable接口两种基本方式。另外,还有Callable和Future的方式,可以获取线程的执行结果。此外,线程池也是一个重要的方法,如Executor框架,这在引用[3]中提到线程池可以优化资源管理。 引用[4]提到,实现Runnable接口可以让多个线程共享同一个实例,适合资源共享的场景。而继承Thread可能更适合需要重写特定方法的场景。不过,实际项目中更推荐实现Runnable或使用线程池,因为避免了单继承的限制,并且更灵活。 接下来,需要结合这些引用中的内容,给出具体的实现方式,每种方式的优缺点以及使用场景。例如,直接创建Thread的实例虽然简单,但资源消耗大,不适合高并发。而线程池(如ExecutorService)能有效管理线程生命周期,提高性能。 另外,引用[1]提到Qt中的多线程使用场景,但用户的问题集中在Java,所以可能不需要涉及Qt。但需要确保回答符合用户的实际需求,即Java中的多线程方法。 还要注意用户提到的“实际项目中的使用示例”,所以每个方法都需要给出代码示例,比如Runnable的实现,线程池的创建等。例如,引用[4]中的MyRunnable示例,可以展示如何实现Runnable接口。 此外,引用[3]强调线程安全和同步机制,所以在示例中可能需要提到synchronized关键字或其他锁机制,但用户的问题主要是创建方法,所以可能简要提及即可,或者放在注意事项里。 需要检查是否有遗漏的方式,比如Callable和Future,这在需要返回结果时使用。线程池的不同型,比如newFixedThreadPool、newCachedThreadPool等,也是实际常用的。 总结一下,回答的结构应该是: 1. 实现Runnable接口:示例代码,优点,适用场景。 2. 继承Thread:示例,但说明局限性。 3. 使用Callable和Future:示例,获取返回值。 4. 线程池(Executor框架):示例,推荐的原因,如资源复用。 同时,结合引用中的信息,比如引用[4]提到的共享同一个Runnable实例,需要说明线程安全的问题,比如是否适合共享资源。 最后,相关问题部分需要生成几个相关的问题,比如线程池配置、线程安全处理、优缺点比较等,可以参考用户给的示例中的结构。</think>### 实际开发中多线程常用方法 在实际项目中,多线程创建和管理需兼顾性能与资源控制。以下是几种常见的实现方式及其示例: --- #### 1. **实现 `Runnable` 接口** **核心思想**:将线程任务与线程对象解耦,避免单继承限制,适合资源共享场景。 **示例代码**: ```java public class MyRunnable implements Runnable { @Override public void run() { System.out.println("线程执行任务:" + Thread.currentThread().getName()); } } // 使用示例 public static void main(String[] args) { MyRunnable task = new MyRunnable(); new Thread(task).start(); // 启动线程 } ``` **优点**: - 支持多线程共享同一个 `Runnable` 实例[^4]。 - 适用于需要批量处理相同任务的场景(如文件分片下载)。 --- #### 2. **继承 `Thread` ** **核心思想**:直接重写 `run()` 方法,但灵活性较低(因Java不支持多继承)。 **示例代码**: ```java public class MyThread extends Thread { @Override public void run() { System.out.println("线程执行任务:" + this.getName()); } } // 使用示例 public static void main(String[] args) { new MyThread().start(); } ``` **局限性**: - 任务与线程绑定,复用性差; - 不推荐在复杂项目中大量使用。 --- #### 3. **使用 `Callable` 和 `Future`** **核心思想**:允许线程返回计算结果,适用于需要异步获取结果的场景(如并行计算)。 **示例代码**: ```java import java.util.concurrent.*; public class MyCallable implements Callable<String> { @Override public String call() { return "任务执行结果"; } } // 使用示例 public static void main(String[] args) throws Exception { ExecutorService executor = Executors.newSingleThreadExecutor(); Future<String> future = executor.submit(new MyCallable()); System.out.println(future.get()); // 阻塞获取结果 executor.shutdown(); } ``` **优点**: - 支持返回值与异常处理; - 结合线程池可提升资源利用率[^3]。 --- #### 4. **线程池(`Executor` 框架)** **核心思想**:通过池化技术复用线程,减少创建/销毁开销,适合高并发场景[^3]。 **示例代码**: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolDemo { public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(4); // 固定大小线程池 for (int i = 0; i < 10; i++) { pool.submit(() -> { System.out.println("线程执行:" + Thread.currentThread().getName()); }); } pool.shutdown(); } } ``` **适用场景**: - 批量处理请求(如HTTP请求并发发送); - 执行短生命周期任务(如日志异步写入)[^2]。 --- ### 选择建议 - **简单任务**:优先使用 `Runnable`; - **需返回值**:选择 `Callable` + `Future`; - **高并发场景**:务必使用线程池(如 `ExecutorService`)[^3][^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值