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()方法启动. //线程创建方式一 : /* 第一步:继 ...
随机推荐
- JQuery-Dialog(弹出窗口,遮蔽窗口)
在Ajax中经常用到的弹出窗口和遮蔽窗口.自己写肯定是一个最佳方案,但时间和成本上,还是决定了寻找现成的吧.大概罗列一下.需要我满足我几个条件 一定要简洁方便 拥有遮蔽功能,Model Dialog ...
- Java复习3-类的继承
前言 本次学习面向对象设计的另外一个基本概念:继承(inheritance).这是Java程序设计中的一项核心技术.另外,还要学习反射(reflection)的概念. 继承 类.超类.子类 publi ...
- 机器学习算法与Python实践之(六)二分k均值聚类
http://blog.csdn.net/zouxy09/article/details/17590137 机器学习算法与Python实践之(六)二分k均值聚类 zouxy09@qq.com http ...
- PDO 增删改查封装的类
Selecting Data 你在mysql_*中是这样做的 <?php $result = mysql_query('SELECT * from table') or die(mysql_er ...
- VC++ MFC应用程序项目文件2.cpp
//GameServer.cpp: 定义应用程序的入口点. // #include "stdafx.h" #include "GameServer.h" #de ...
- PostBuildEvent
<PostBuildEvent>CALL "%25VS90COMNTOOLS%25\vsvars32.bat" > NULL sn –Vr $(TargetFil ...
- windows 环境变量
1.考虑下面的需求,进入cmd之后,我就想执行mysql客户端命令,而这需要转到mysql安装目录,找到mysql可执行文件,在这个目录下执行mysql命令.这样太麻烦,有没有好的解决办法? 2.使用 ...
- Android 演示 DownloadManager——Android 下载 apk 包并安装
本文内容 环境 项目结构 演示下载 参考资料 本文是 github 上 Trinea-Android-common 和 Trinea-Android-Demo 项目的一部分,将下载部分分离出来,看看如 ...
- 电子商务 B2C 结构图【转载+整理】
本文内容 商品展示 内容展示 订单确认 支付系统 用户中心 商品&促销 CRM 订单处理 WMS 采购管理 财务管理 报表管理 系统设置 WA系统 商品展示 按照 Ebay 内部分类,任何 ...
- apache 反向代理的时候,通过域名访问是,出现跳转到ip或者无权访问的情况
解决方法很简单,在配置反向代理的时候加上一行: ProxyPreserveHost On 例如:ProxyPass / http://202.112.0.1/ProxyPassReverse / ht ...