千家信息网

怎么实现Java多线程并发

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要介绍"怎么实现Java多线程并发",在日常操作中,相信很多人在怎么实现Java多线程并发问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"怎么实现Java多线程
千家信息网最后更新 2026年11月04日怎么实现Java多线程并发

这篇文章主要介绍"怎么实现Java多线程并发",在日常操作中,相信很多人在怎么实现Java多线程并发问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"怎么实现Java多线程并发"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

  继承 Thread 类

  Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线程,并执行 run()方法。

public class MyThread extends Thread {

public void run() {

System.out.println("MyThread.run()");

} }

MyThread myThread1 = new MyThread();

myThread1.start();

实现 Runnable 接口

如果自己的类已经 extends 另一个类,就无法直接 extends Thread,此时,可以实现一个Runnable 接口。

public class MyThread extends OtherClass implements Runnable {

public void run() {

System.out.println("MyThread.run()");

} } //启动

MyThreadMyThread myThread = new MyThread();

Thread thread = new Thread(myThread);

thread.start();

target.run()public void run() {

if (target != null) {

target.run();

} }

ExecutorService、Callable、Future 有返回值线程

有返回值的任务必须实现 Callable 接口,类似的,无返回值的任务必须 Runnable 接口。执行Callable 任务后,可以获取一个 Future 的对象,在该对象上调用 get 就可以获取到 Callable 任务返回的 Object 了,再结合线程池接口 ExecutorService 就可以实现传说中有返回结果的多线程了。

//创建一个线程池

ExecutorService pool = Executors.newFixedThreadPool(taskSize);

// 创建多个有返回值的任务

List list = new ArrayList();

for (int i = 0; i < taskSize; i++) {

Callable c = new MyCallable(i + " ");

// 执行任务并获取 Future 对象

Future f = pool.submit(c); list.add(f);

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

// 获取所有并发任务的运行结果for (Future f : list) {

// 从 Future 对象上获取任务的返回值,并输出到控制台System.out.println("res:" + f.get().toString());

}

基于线程池的方式

线程和数据库连接这些资源都是非常宝贵的资源。如果每次需要的时候创建,不需要的时候销毁,是非常浪费资源的。那么我们就可以使用缓存的策略,也就是使用线程池。

// 创建线程池ExecutorService threadPool = Executors.newFixedThreadPool(10);

while(true) { threadPool.execute(new Runnable() {

// 提交多个线程执行 @Override public void run() {

System.out.println(Thread.currentThread().getName() + " is running ..");

try {

Thread.sleep(3000);

}

catch (InterruptedException e) {

e.printStackTrace();

} } }); }}

2 同步锁与死锁

同步锁当多个线程同时访问同一个数据时,很容易出现问题。为了避免这种情况出现,我们要保证线程同步互斥,就是指并发执行的多个线程,在同一时间内只允许一个线程访问共享数据。Java中可以使用synchronized关键字来取得一个对象的同步锁。

死锁何为死锁,就是多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。

3 线程池原理

线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其它线程执行完毕,再从队列中取出任务来执行。主要特点为:线程复用;控制最大并发数;管理线程。

线程复用一个Thread的类都有一个start方法。当调用start启动线程时Java虚拟机会调用该类的 run 方法。那么该类的 run() 方法中就是调用了 Runnable 对象的 run() 方法。我们可以继承重写 Thread 类,在其 start 方法中添加不断循环调用传递过来的 Runnable 对象。这就是线程池的实现原理。循环方法中不断获取 Runnable 是用 Queue 实现的,在获取下一个 Runnable 之前可以是阻塞的。

线程池的组成一般的线程池主要分为以下 4 个组成部分:

(1)线程池管理器:用于创建并管理线程池。(2)工作线程:线程池中的线程。(3)任务接口:每个任务必须实现的接口,用于工作线程调度其运行。(4)任务队列:用于存放待处理的任务,提供一种缓冲机制。

Java 中的线程池是通过 Executor 框架实现的,该框架中用到了 Executor,Executors,ExecutorService,ThreadPoolExecutor ,Callable 和 Future、FutureTask 这几个类。

ThreadPoolExecutor 的构造方法如下:

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize, long keepAliveTime,TimeUnit unit, BlockingQueue workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);}

corePoolSize:指定了线程池中的线程数量。

maximumPoolSize:指定了线程池中的最大线程数量。

keepAliveTime:当前线程池数量超过 corePoolSize 时,多余的空闲线程的存活时间,即多次时间内会被销毁。

unit:keepAliveTime 的单位。

workQueue:任务队列,被提交但尚未被执行的任务。

threadFactory:线程工厂,用于创建线程,一般用默认的即可。

handler:拒绝策略,当任务太多来不及处理,如何拒绝任务。

拒绝策略线程池中的线程已经用完了,无法继续为新任务服务,同时,等待队列也已经排满了,再也塞不下新任务了。这时候我们就需要拒绝策略机制合理的处理这个问题。

JDK 内置的拒绝策略如下:

AbortPolicy :直接抛出异常,阻止系统正常运行。

CallerRunsPolicy :只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。

DiscardOldestPolicy :丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。

DiscardPolicy :该策略默默地丢弃无法处理的任务,不予任何处理。如果允许任务丢失,这是最好的一种方案。

以上内置拒绝策略均实现了 RejectedExecutionHandler 接口,若以上策略仍无法满足实际需要,完全可以自己扩展 RejectedExecutionHandler 接口。

Java 线程池工作过程(1)线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上执行它们。

(2)当调用 execute() 方法添加一个任务时,线程池会做如下判断:

a) 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;

b) 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;

c) 如果这时候队列满了,而且正在运行的线程数量小maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;

d) 如果队列满了,而且正在运行的线程数量大于或等maximumPoolSize,那么线程池会抛出异常 RejectExecutionException。

(3)当一个线程完成任务时,它会从队列中取下一个任务来执行。

(4)当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。

到此,关于"怎么实现Java多线程并发"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

线程 任务 方法 运行 数量 队列 接口 策略 对象 多个 就是 处理 时间 正在 资源 同步 学习 最大 同时 实例 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 花魁咖啡 广州万易互联网科技有限公司 高科技互联网 科技创新与互联网经济 未来的互联网科技 有木互联网科技 互联网金融 科技创新 剑昆互联网络科技有限公司临桂 以后互联网后是啥科技 互联网金融中的现代科技 福建科技产业互联网发展 崇明区互联网教育科技诚信经营 互联网科技研发水平 中科明德北京互联网科技 南通创西澳互联网科技有限公司 电子商务与互联网科技的关系 张召忠谈中国互联网科技 35岁以上互联网科技行业 江苏互联网科技小贷 湖北辰鑫科技互联网 互联网科技有限公司 广东猪兼强互联网科技有限公司 河南云网互联网络科技有限公司 中国互联网科技股 湖南一路畅行互联网科技 上海京穆互联网科技有限公司 中国新注册互联网科技 亚光科技低轨卫星互联网 陕西彩京云互联网科技有限公司 瑞安市蟠桃会互联网科技有限公司
0