Java实现多线程的四种实现方式
以计算0到1000之间的和为例
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
//求1~N全部整数的和,会上溢
int N = (int) 1e8;
int threadSize = 5;
/**
* 最原始最基础的方式:使用thread,自定义并发
*/
class ThreadJoin {
void go() {
Thread[] a = new Thread[threadSize];
//每个线程应该干多少活
int per = (int) Math.ceil(N * 1.0 / a.length);
final AtomicInteger s = new AtomicInteger(0);
for (int i = 0; i < a.length; i++) {
int ii = i;
a[i] = new Thread(() -> {
int sum = 0;
for (int j = ii * per; j < Math.min(ii * per + per, N); j++) {
sum += j;
}
s.addAndGet(sum);
});
a[i].start();
}
for (Thread i : a)
try {
i.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(s.get() + " " + getClass().getName());
}
}
/**
* 重量级的多线程框架:ThreadPoolExecutor,维护一个动态线程池
*/
class UseThreadPoolExecutor {
void go() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(threadSize, threadSize, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
int per = (int) (Math.ceil(1.0 * N / threadSize));
List<Future<Integer>> futureList = new LinkedList<>();
for (int i = 0; i < threadSize; i++) {
final int ii = i;
futureList.add(executor.submit(() -> {
int sum = 0;
for (int j = ii * per; j < Math.min(N, ii * per + per); j++) {
sum += j;
}
return sum;
}));
}
int sum = 0;
for (Future<Integer> j : futureList) {
try {
sum += j.get(Integer.MAX_VALUE, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
}
executor.shutdown();
System.out.println(sum + " " + getClass().getName());
}
}
/**
* ExecutorService:轻量级的线程池
*/
class UseExecutorService {
void go() {
ExecutorService service = Executors.newFixedThreadPool(threadSize);
int per = (int) (Math.ceil(N * 1.0 / threadSize));
List<Future<Integer>> futureList = new LinkedList<>();
for (int i = 0; i < threadSize; i++) {
final int ii = i;
futureList.add(service.submit(() -> {
int sum = 0;
for (int j = ii * per; j < Math.min(N, ii * per + per); j++) {
sum += j;
}
return sum;
}));
}
int sum = 0;
for (Future<Integer> j : futureList) {
try {
sum += j.get(Integer.MAX_VALUE, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
}
service.shutdown();
System.out.println(sum + " " + getClass().getName());
}
}
/**
* 模拟Linux fork join操作
*/
class UseForkJoin {
void go() {
int per = (int) (Math.ceil(1.0 * N / threadSize));
List<ForkJoinTask<Integer>> a = new ArrayList<>(threadSize);
for (int i = 0; i < threadSize; i++) {
final int ii = i;
a.add(new RecursiveTask<Integer>() {
@Override
protected Integer compute() {
int sum = 0;
for (int j = ii * per; j < Math.min(N, ii * per + per); j++) {
sum += j;
}
return sum;
}
});
a.get(i).invoke();
}
int s = 0;
for (ForkJoinTask<Integer> i : a) {
s += i.join();
}
System.out.println(s + " " + getClass().getName());
}
}
Main() {
new ThreadJoin().go();
new UseExecutorService().go();
new UseThreadPoolExecutor().go();
new UseForkJoin().go();
}
public static void main(String[] args) {
new Main();
}
}
Java实现多线程的四种实现方式的更多相关文章
- Java线程池的四种创建方式
Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFix ...
- java多线程的四种实现方式
主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorService.Callable.Futur ...
- XML解析——Java中XML的四种解析方式
XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性.给数据集成与交互带来了极大的方便.XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已. XML的解析方式分为四 ...
- XML解析——Java中XML的四种解析方式(转载 by 龍清扬)
XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性.给数据集成与交互带来了极大的方便.XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已. XML的解析方式分为四 ...
- Java中XML的四种解析方式(一)
XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性给数据集成与交互带来了极大的方便.XML在不同的语言环境中解析的方式都是一样的,只不过实现的语法不同而已. XML文档以层级标签的 ...
- JAVA实现多线程的四种方式
JAVA多线程实现方式: 1.继承Thread类(无返回值) 2.实现Runnable接口(无返回值) 3.实现Callable接口,通过FutureTask包装器来创建Threak线程(有返回值) ...
- Java中XML的四种解析方式(二)
三.JDOM解析 特征: 1.仅使用具体类,而不使用接口. 2.API大量使用了Collections类. import org.jdom2.Attribute; import org.jdom2.D ...
- Java事件监听器的四种实现方式
自身类作为事件监听器 外部类作为事件监听器 匿名内部类作为事件监听器 内部类作为事件监听器 自身类作为事件监听器: import javax.swing.*; import java.awt.*; i ...
- java中多线程的两种创建方式
一丶继承Thread类实现多线程 第一步:继承Thread类第二步:重写run()方法第三步:创建继承了Thread类的对象 , 调用start()方法启动. //线程创建方式一 : /* 第一步:继 ...
随机推荐
- 发布一个高效的JavaScript分析、压缩工具 JavaScript Analyser
发布一个高效的JavaScript分析.压缩工具 JavaScript Analyser 先发一段脚本压缩示例,展示一下JSA语法压缩和优化功能. try { //xxxx(); } catch (e ...
- pThreads线程(二) 线程同步--互斥量/锁
互斥量(Mutex)是“mutual exclusion”的缩写.互斥量是实现线程同步,和保护同时写共享数据的主要方法. 互斥量对共享数据的保护就像一把锁.在Pthreads中,任何时候仅有一个线程可 ...
- Android -- EventBus解析
EventBus EventBus 是一个 Android 事件发布/订阅框架,通过解耦发布者和订阅者简化 Android 事件传递.传统的事件传递方式包括:Handler.BroadCastRece ...
- __attribute__中constructor和destructor[总结]
1.前言 最近看到一份代码,看到一个函数前面用__attribute__((destructor))修饰,当时感觉有点怪怪的,搜了整个程序,也没发现哪个地方调用这个函数.于是从字面意思猜想,该函数会在 ...
- wamp因配置错误而导致apache无法启动的问题
在使用wamp搭建一个PHP项目环境时,却出现了apache无法启动的问题 通过查看window的错误日志才发现apache出现了错误 错误的原因说的很清楚,是因为配置文件中的Director ...
- OpenNebula学习第三节之虚拟机管理
一.背景 已经安装好OpenNebula-Front-end 已经安装好OpenNebula Node 已经把Node注册到Front-end 二.目标 看过第一.二节的同学们可能已经知道我的整个环境 ...
- Softmax 函数的特点和作用是什么?
作者:张欣链接:https://www.zhihu.com/question/23765351/answer/98897364来源:知乎著作权归作者所有,转载请联系作者获得授权. softmax 回归 ...
- Windows系统内存分析工具的介绍
Windows系统内存分析工具的介绍(进程管理器,资源管理器,性能监视器, VMMap, RamMap,PoolMon) 微软官方提供多种工具来分析Windows 的内存使用情况,除了系统自带的任 ...
- Ant编译utf-8非法字符:/65279 解决方法
原文链接:http://blog.csdn.net/xiyuan1999/article/details/5989336 Ant编译utf-8非法字符:/65279 解决方法 使用ant编译j ...
- Modbus常用功能码协议详解
Modbus常用功能码协议详解 01H-读线圈状态 1)描述:读从机线圈寄存器,位操作,可读单个或者多个: 2)发送指令: 假设从机地址位0x01,寄存器开始地址0x0023,寄存器结束抵制0x003 ...