以计算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实现多线程的四种实现方式的更多相关文章

  1. Java线程池的四种创建方式

    Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFix ...

  2. java多线程的四种实现方式

    主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorService.Callable.Futur ...

  3. XML解析——Java中XML的四种解析方式

    XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性.给数据集成与交互带来了极大的方便.XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已. XML的解析方式分为四 ...

  4. XML解析——Java中XML的四种解析方式(转载 by 龍清扬)

    XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性.给数据集成与交互带来了极大的方便.XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已. XML的解析方式分为四 ...

  5. Java中XML的四种解析方式(一)

    XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性给数据集成与交互带来了极大的方便.XML在不同的语言环境中解析的方式都是一样的,只不过实现的语法不同而已. XML文档以层级标签的 ...

  6. JAVA实现多线程的四种方式

    JAVA多线程实现方式: 1.继承Thread类(无返回值) 2.实现Runnable接口(无返回值) 3.实现Callable接口,通过FutureTask包装器来创建Threak线程(有返回值) ...

  7. Java中XML的四种解析方式(二)

    三.JDOM解析 特征: 1.仅使用具体类,而不使用接口. 2.API大量使用了Collections类. import org.jdom2.Attribute; import org.jdom2.D ...

  8. Java事件监听器的四种实现方式

    自身类作为事件监听器 外部类作为事件监听器 匿名内部类作为事件监听器 内部类作为事件监听器 自身类作为事件监听器: import javax.swing.*; import java.awt.*; i ...

  9. java中多线程的两种创建方式

    一丶继承Thread类实现多线程 第一步:继承Thread类第二步:重写run()方法第三步:创建继承了Thread类的对象 , 调用start()方法启动. //线程创建方式一 : /* 第一步:继 ...

随机推荐

  1. MongoDB分页的Java实现和分页需求的思考

    前言 传统关系数据库中都提供了基于row number的分页功能,切换MongoDB后,想要实现分页,则需要修改一下思路. 传统分页思路 假设一页大小为10条.则 //page 1 1-10 //pa ...

  2. OpenWrt Web界面修改及功能实现实例说明

    http://www.cnblogs.com/dwayne/archive/2012/04/21/2460830.html 通过上篇文章的介绍,我们应该了解了Lua语言在OpenWrt Web配置页面 ...

  3. java注解Annotation的使用实例

    1.注解的定义 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java. ...

  4. android中LitePal的使用

    网上有一篇文章写的挺好的,推荐给大家:安卓项目实战之:数据库框架 LitePal 3.0 的使用详解 LitePal是对SQLite数据库操作进行了封装,采用对象映射的方式操作SQLite数据库,简化 ...

  5. 【转载】TypeScript学习笔记——var与let

    var 与  let 都是TypeScript里的变量声明方式 两者非常相似,在语法不存在很大的差异,而在语义上存在很大的区别 块作用域 var有着些奇怪的作用域规则 例如 function f(ru ...

  6. 微软BI 之SSRS 系列 - 不显示 Pie Chart 饼图上 0% 的数据

    SSRS 小技巧系列专门用来记录 SSRS 报表开发过程中常用的小技巧 - 效果图 - 0% 的标签数据不需要显示出来. 效果图 - 正常的效果. 解决方法 - 使用 IIF 条件判断,如果计算值为 ...

  7. LUN mask 和zone 区别

    问题: 在SAN网络中,只有一台存储时,该存储带有Map功能,可以将LUN Map到指定主机,那么FC Switch的zoning功能还有意义吗?有没有方法来证明这以意义的存在.即使存储不带有Map功 ...

  8. MySql服务初始化、安装、启动

    /// <summary> /// 安装并开启服务 /// </summary> public static bool InitAndStartService(string s ...

  9. 演示一下:rm -rf /

  10. sqlserver 建表语句,获取建表语句的存储过程,包括排序规则,索引,字段说明,支持同时生成多个表

    先创建一个分割表名的分割函数 --表值函数用以截取字符串 --如果为其添加一列主键id,则其顺序就会固定了 create FUNCTION [Split](@text NVARCHAR(max)) ) ...