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()方法启动. //线程创建方式一 : /* 第一步:继 ...
随机推荐
- ztree默认自动打开第一级
var treeObj = $.fn.zTree.getZTreeObj("tree"); var nodes = treeObj.getNodes(); if (nodes.le ...
- IOS开发之自定义UITabBarController
UITabBarController是开发中经常会用到的一个视图控制器,但是默认的UITabBarController经常不能够完全满足我们的需求,所以我们经常需要自定义一个UITabBarContr ...
- pThreads线程(二) 线程同步--互斥量/锁
互斥量(Mutex)是“mutual exclusion”的缩写.互斥量是实现线程同步,和保护同时写共享数据的主要方法. 互斥量对共享数据的保护就像一把锁.在Pthreads中,任何时候仅有一个线程可 ...
- Thinkphp5 使用odbc连接到sqlserver
在PHP中访问mssql有两个方式 1.安装相应的驱动,如sqlsrv 2.直接使用PHP自带的ODBC驱动(不需要安装) 本文直接使用自带的ODBC驱动 在使用前请确定PHP开启了php_pdo ...
- java.security.NoSuchAlgorithmException: Cannot find any provider supporting DESede/CBC/PKCS5Padding
最近在做3DES加密,在本地window下面运行ok的程序,放到linux环境上竟然报错: Java.security.NoSuchAlgorithmException: Cannot find an ...
- ecshop中smarty最常用的6大基本语法
模板制作比较核心的其实就是变量的使用,因为这些就是数据的根本,想从数据库里获取数据并显示在界面就必须使用smarty来展示,下面是关于smarty的介绍和使用.Smarty是一个php模板引擎,它分开 ...
- css调整图片位置布局
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE wml PUBLIC "-//WAP ...
- Objective-C编程 - 关于Block的要点
1. 首先,我们快速过一下,什么是Block? Block是一段代码,它在OC中以^开头,可以有返回值,和参数列表,但就是没有名字. 所以,你可以把它认为是匿名函数. 事实上,它和Swift中的闭包( ...
- 使用gradle的application插件进行Spring-boot项目打包
1:在build.gradle中增加以下配置 fat jar并不总是一个合适的选择,比如需要依赖跟jar分离,使用gradle的application插件就可以做到. 在GradleTest项目中,b ...
- ngx_http_upstream_keepalive
链接:http://wiki.nginx.org/HttpUpstreamKeepaliveModule 今天看了一些代码: upstream b_memc2 { server ; keepalive ...