Java多线程
多线程是指同时执行多个线程的能力。Java提供了内置的多线程支持,使得开发者可以轻松地创建和管理多个并发执行的线程
多线程
Process
Process(进程)是指正在运行的一个程序实例;Java提供了Process类,用于创建和控制外部进程
Thread
Thread(线程)是指执行线程任务的单个执行单元;Java提供了Thread类,用于创建和管理线程
线程创建方式
继承Thread类
代码语言:java复制开发者可以创建一个继承自Thread类的子类,并重写其run()方法来定义线程的执行逻辑;然后通过创建该子类的实例,调用start()方法来启动线程
class MyThread extends Thread {
public void run() {
// 线程执行的逻辑
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
}
实现Runnable接口
代码语言:java复制开发者可以创建一个实现了Runnable接口的类,并实现其run()方法来定义线程的执行逻辑;然后通过创建该类的实例,将其作为参数传递给Thread类的构造函数,最后调用start()方法来启动线程
class MyRunnable implements Runnable {
public void run() {
// 线程执行的逻辑
}
}
public class Main {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start(); // 启动线程
}
}
实现Callable接口
代码语言:java复制Callable接口代表一个可以在当前线程中执行的代码块,但它可以返回结果;因此,Runnable接口适用于那些不需要返回结果的操作,而Callable接口适用于那些需要返回结果的操作
class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
// 在这里编写你的逻辑代码
// 返回你的结果
return 42;
}
}
public class Main {
public static void main(String[] args) throws Exception {
// 创建一个线程池
ExecutorService executorService = Executors.newSingleThreadExecutor();
// 创建一个Callable任务
Callable<Integer> callable = new MyCallable();
// 提交任务并获得一个Future对象
Future<Integer> future = executorService.submit(callable);
// 等待任务执行完成并获取结果
Integer result = future.get();
// 输出结果
System.out.println("Result: " result);
// 关闭线程池
executorService.shutdown();
}
}
代理模式
Java的代理模式是一种结构型设计模式,它允许在不改变现有代码的情况下,为对象提供一个代理,以控制对该对象的访问。代理模式可以用于实现对象的“守卫”或“代理”,可以在运行时对对象的行为进行修改或增强
- 抽象角色:代理角色和真实角色对外提供的公共方法,常是一个抽象数据类型或接口
- 真实角色:需要实现抽象角色接口,定义真正所要实现的业务逻辑,以便代理角色调用
- 代理角色:需要实现抽象角色接口,真实角色的代理,通过真实角色的业务逻辑来实现抽象方法,并可以附加自己的操作,将统一的流程控制都放到代理角色中处理
动态代理
动态代理是通过实现java.lang.reflect.Proxy接口来创建代理对象,代理对象可以在运行时动态地生成;动态代理通常用于实现AOP(面向切面编程)等场景
静态代理
代码语言:java复制静态代理(Static Proxy)是一种通过编写代码来拦截并修改对象行为的技术;静态代理使用Java字节码操作,可以在运行时生成代理类,对代理对象进行增强;静态代理主要使用Java反射机制实现
//抽象角色(手机厂家)
public interface PhoneFactory {
void deliverGoods();
}
//真实角色
public class Xiaomi implements PhoneFactory {
@Override
public void deliverGoods() {
System.out.println("小米手机....发货了");
}
}
//真实角色
public class Huawei implements PhoneFactory {
@Override
public void deliverGoods() {
System.out.println("华为手机....发货了");
}
}
//代理角色
public class JD implements PhoneFactory {
private PhoneFactory factory;
public JD(PhoneFactory factory) {
this.factory = factory;
}
private void sailBefore() {
System.out.println("售前服务");
}
private void sailAfter() {
System.out.println("售后服务");
}
//对真实角色的行为(方法)进行增强
@Override
public void deliverGoods() {
sailBefore();
factory.deliverGoods();
sailAfter();
}
}
//调用者
public class ShoppingTest {
public static void main(String[] args) {
PhoneFactory haier = new Huawei();
JD jd = new JD(haier);
jd.deliverGoods();
}
}
//拓展需求,购买OPPO手机
public class OPPO implements PhoneFactory{
@Override
public void deliverGoods() {
System.out.println("OPPO手机....发货了");
}
}
//调用者
public class ShoppingTest {
public static void main(String[] args) {
Factory oppo = new OPPO();
JD jd = new JD(oppo);
jd.deliverGoods();
}
}
线程方法
线程生命周期
多线程适用场景
1、并发处理: 如果需要同时处理多个任务或请求,可以使用线程来并发执行这些任务。在 Java 中,可以使用 Thread 类或实现 Runnable 接口创建线程,并通过 start() 方法启动线程 异步操作: 在某些情况下,需要进行异步操作,例如处理耗时的操作、IO 操作或网络请求。使用线程可以在后台执行这些操作,而不会阻塞主线程。在 Java 中,可以使用 ExecutorService、CompletableFuture、FutureTask 等来实现异步操作
2、定时任务: 需要按照一定的时间间隔或时间表执行任务,可以使用线程来执行定时任务。在 Java 中,可以使用 Timer、ScheduledExecutorService 或第三方库如 Quartz 来执行定时任务 并行计算: 在需要并行计算的场景中,可以使用线程来同时执行计算任务,从而加速处理速度。在 Java 中,可以使用 ExecutorService、ForkJoinPool 等来实现并行计算。
3、多线程数据处理: 如果有大量的数据需要处理,可以使用多线程来并行处理数据。例如,将数据分割成多个部分,每个线程处理一个部分,并将结果合并。在 Java 中,可以使用 ExecutorService、ForkJoinPool、并发集合类等来实现多线程数据处理 4、线程池: 在需要管理线程的创建、复用和销毁时,可以使用线程池来提高性能和资源利用率。线程池可以预先创建一组线程,并维护一个任务队列,以便在需要时执行任务。在 Java 中,可以使用 ExecutorService、ThreadPoolExecutor 来创建和管理线程池