以计算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. ztree默认自动打开第一级

    var treeObj = $.fn.zTree.getZTreeObj("tree"); var nodes = treeObj.getNodes(); if (nodes.le ...

  2. IOS开发之自定义UITabBarController

    UITabBarController是开发中经常会用到的一个视图控制器,但是默认的UITabBarController经常不能够完全满足我们的需求,所以我们经常需要自定义一个UITabBarContr ...

  3. pThreads线程(二) 线程同步--互斥量/锁

    互斥量(Mutex)是“mutual exclusion”的缩写.互斥量是实现线程同步,和保护同时写共享数据的主要方法. 互斥量对共享数据的保护就像一把锁.在Pthreads中,任何时候仅有一个线程可 ...

  4. Thinkphp5 使用odbc连接到sqlserver

    在PHP中访问mssql有两个方式 1.安装相应的驱动,如sqlsrv 2.直接使用PHP自带的ODBC驱动(不需要安装)   本文直接使用自带的ODBC驱动 在使用前请确定PHP开启了php_pdo ...

  5. java.security.NoSuchAlgorithmException: Cannot find any provider supporting DESede/CBC/PKCS5Padding

    最近在做3DES加密,在本地window下面运行ok的程序,放到linux环境上竟然报错: Java.security.NoSuchAlgorithmException: Cannot find an ...

  6. ecshop中smarty最常用的6大基本语法

    模板制作比较核心的其实就是变量的使用,因为这些就是数据的根本,想从数据库里获取数据并显示在界面就必须使用smarty来展示,下面是关于smarty的介绍和使用.Smarty是一个php模板引擎,它分开 ...

  7. css调整图片位置布局

    <?xml version="1.0" encoding="utf-8"?><!DOCTYPE wml PUBLIC "-//WAP ...

  8. Objective-C编程 - 关于Block的要点

    1. 首先,我们快速过一下,什么是Block? Block是一段代码,它在OC中以^开头,可以有返回值,和参数列表,但就是没有名字. 所以,你可以把它认为是匿名函数. 事实上,它和Swift中的闭包( ...

  9. 使用gradle的application插件进行Spring-boot项目打包

    1:在build.gradle中增加以下配置 fat jar并不总是一个合适的选择,比如需要依赖跟jar分离,使用gradle的application插件就可以做到. 在GradleTest项目中,b ...

  10. ngx_http_upstream_keepalive

    链接:http://wiki.nginx.org/HttpUpstreamKeepaliveModule 今天看了一些代码: upstream b_memc2 { server ; keepalive ...