首页 > 编程语言 >java多线程

java多线程

时间:2023-08-31 18:00:35浏览次数:37  
标签:异步 java Thread class 线程 executor 多线程 public

  1. 实现 Runnable 接口
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的代码
    }
}

然后在主线程中创建一个线程对象,并启动该线程:

Thread thread = new Thread(new MyRunnable());
thread.start();
  1. 继承 Thread 类
public class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行的代码
    }
}

然后在主线程中创建该线程对象,并启动该线程:

MyThread thread = new MyThread();
thread.start();

在上述两种方式中,都需要在一个独立的线程中运行代码,这就要求我们将需要多线程执行的代码放到一个特定的代码块或方法中,然后将其作为参数传递给 Thread 或 Runnable 对象。

需要注意的是,在使用多线程时,应该避免线程之间的冲突和数据竞争。可使用同步机制,如 synchronized 关键字、Lock 对象等来保证线程安全。

同时,Java 还提供了一些线程池的实现,如 ThreadPoolExecutor 等,用于管理多个线程的执行和资源分配。


java线程池的创建

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        // 创建固定大小的线程池,同时运行5个线程
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        // 提交任务到线程池执行
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            executorService.execute(() -> {
                System.out.println("Task " + taskId + " is being executed by " + Thread.currentThread().getName());
                try {
                    Thread.sleep(2000); // 模拟任务执行时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskId + " has been completed.");
            });
        }

        // 关闭线程池
        executorService.shutdown();
    }
}

这个代码示例创建了一个包含 5 个线程的固定大小线程池。然后,通过循环提交了10个任务到线程池中执行。每个任务会打印自己的任务号和正在执行的线程名称,并模拟了一个耗时的任务。


@Asycn注解搭配线程池的使用

首先,在你的 Spring Boot 应用主类中加上 @EnableAsync 注解开启异步方法执行功能:

@SpringBootApplication
@EnableAsync  // 开启异步方法执行功能
public class MyApplication {
    // ...
}

然后,定义一个用于执行异步任务的线程池:

@Configuration
public class ThreadPoolConfig {
    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);        // 核心线程数
        executor.setMaxPoolSize(10);        // 最大线程数
        executor.setQueueCapacity(25);      // 队列容量
        executor.setKeepAliveSeconds(300);  // 线程池维护线程所允许的空闲时间
        executor.setThreadNamePrefix("my-pool-"); // 线程名前缀
        executor.initialize();              // 初始化 executor
        return executor;
    }
}

在上面的代码中,通过 ThreadPoolTaskExecutor 类创建了一个线程池,并设置了一些常用参数,例如核心线程数、最大线程数、队列容量等。

接下来,我们定义一个异步任务,使用 @Async 注解标记它为异步方法:

@Service
public class MyService {
    @Async("taskExecutor")  // 使用名为 "taskExecutor" 的线程池执行该方法
    public void asyncMethod() {
        System.out.println("异步方法被调用,线程名:" + Thread.currentThread().getName());
        try {
            Thread.sleep(2000); // 模拟一个耗时的操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("异步方法执行完成。");
    }
}

在上面的代码中,我们使用 @Async 注解,指定了要使用的线程池名称为 "taskExecutor",然后定义了一个异步任务,其中包含了一些打印和模拟耗时操作的代码。

最后,我们在 Controller 中调用异步方法:

@RestController
public class MyController {
    @Autowired
    private MyService myService;

    @GetMapping("/async")
    public String async() {
        myService.asyncMethod(); // 调用异步方法
        return "Async method is being executed.";
    }
}

在上面的代码中,我们注入了 MyService 服务实例,并在 /async 请求处理器中调用了异步方法 asyncMethod()

运行应用程序,访问 /async URL,我们会看到异步方法被调用,但是不会阻塞主线程,而是在另一个线程池里执行。同时,在控制台输出中,我们可以看到异步方法执行完成的消息。


标签:异步,java,Thread,class,线程,executor,多线程,public
From: https://blog.51cto.com/u_16205743/7310983

相关文章

  • JavaScript 防抖&节流
    JavaScript的防抖(Debouncing)和节流(Throttling)是两种用于优化高频率事件处理的常见技术。它们都可以限制事件的触发频率,以减少过度触发事件处理函数而导致的性能问题。防抖(Debouncing)防抖是指在事件被触发后,等待一定时间再执行事件处理函数。如果在等待时间内事件再次被触发,那么......
  • Arthas(阿尔萨斯)Java 诊断工具
    Arthas(阿尔萨斯)能为你做什么?Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:1.这个类从哪个jar包加载的?为什么会报各种类相关的Exception?2.我改的代码为什么没有执行到?难道是我没commit?分支搞错了?3.遇到问......
  • 多线程与单线程执行的对比
    对比技术点:单线程:普通循环多线程框架:CompletableFuture多线程框架;ForkJoin50次对比实验 源码: packagecom.example.demo;importorg.apache.commons.lang3.time.StopWatch;importjava.util.ArrayList;importjava.util.List;importjava.util.concurre......
  • java 使用多线程的注意事项
    线程安全:确保共享资源的正确访问和修改,避免并发冲突。可以通过同步机制(如锁、互斥量、信号量等)或使用线程安全的数据结构来实现线程安全。案例:银行账户并发访问importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;classBankAccount{......
  • 多线程执行工具方法
    publicstatic<P,T>List<CompletableFuture<T>>multiThreadRun(Function<P,T>run,Collection<P>list,intthreadSize,Executorexecutor,booleanwaitRunFinal){List<CompletableFuture<T>>cf=newArr......
  • Java中的ThreadLocal详解
     一、ThreadLocal简介多线程访问同一个共享变量的时候容易出现并发问题,特别是多个线程对一个变量进行写入的时候,为了保证线程安全,一般使用者在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性。ThreadLocal是除了加锁这种同步方式之外的一种保证一种规避多线......
  • 1-JAVA-面向对象程序设计概论-笔记整理
    学习之路,长路漫漫,写学习笔记的过程就是把知识讲给自己听的过程。这个过程中,我们去记录思考的过程,便于日后复习,梳理自己的思路。学习之乐,独乐乐,不如众乐乐,把知识讲给更多的人JAVA-面向对象程序设计概论-笔记整理内容提要结构化程序设计方法面向对象技术及UML简介面向对象基本概念面......
  • java练习:使用Stream
    packagecom.example.ss_0203_array.test.test_0830;importjava.util.ArrayList;importjava.util.Collections;importjava.util.stream.Stream;publicclasstest3{publicstaticvoidmain(String[]args){/***按照下面的要求完成集合的创......
  • java directoryAndfileHide
    javaimportjava.io.File;importjava.util.Scanner;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.attribute.DosFileAttributeView;importjava.nio.file.attribute.DosFileAttributes;publicclassDirectoryandFileHIde{pub......
  • Java8知识梳理
    Java8的改进速度更快代码更少(Lambda表达式)引入强大的StreamAPI便于并行最大化减少空指针异常(Optional)Nashorn引擎,允许在JVM上运行js应用并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。相比较串行的流,并行的流可以很大程度上提高程序的执行......