-
2021-03-09 09:14:03
package test;
import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;
public class SumService {
private final Integer nthread;
private final ExecutorService executorService;
private final Lock lock;
private final CountDownLatch countDownLatch;
private Integer sum;
public SumService(){
this.sum = new Integer(0);
this.nthread = new Integer(100);
this.executorService = new ThreadPoolExecutor(10, nthread, 10L, TimeUnit.SECONDS, new ArrayBlockingQueue(nthread));
this.lock = new ReentrantLock();
this.countDownLatch = new CountDownLatch(nthread);
}
public Integer call() throws Exception{
for (int i = 0; i < nthread; i++) {
executorService.execute(()-> sum());
}
executorService.shutdown();
countDownLatch.await();
return sum;
}
private void sum(){
for (int i = 0; i < 10000; i++) {
lock.lock();
sum++;
lock.unlock();
}
countDownLatch.countDown();
}
public static void main(String[] args) throws Exception{
SumService sumService = new SumService();
Integer sum = sumService.call();
System.out.println(sum);
}
} `
来源:站长平台
标签:Java,求和,lock,sum,nthread,private,Integer,new,多线程
来源: https://www.cnblogs.com/1994july/p/12163944.html
更多相关内容 -
Java 多线程求和1+2+3+.....+100;
2021-05-21 15:22:441. 提到Java多线程求和我们首先想到的是new 多个Thread,然后给每个线程内写一个for循环来求和,如下 package Demo1; public class sum { public static void main(String[] args) { new Thread(()->{ int ...1. 提到Java多线程求和我们首先想到的是new 多个Thread,然后给每个线程内写一个for循环来求和,如下
package Demo1; public class sum { public static void main(String[] args) { new Thread(()->{ int sum = 0; for (int i = 0; i < 10; i++) { sum+=i; } System.out.println(sum); }).start(); new Thread(()->{ int sum = 0; for (int i = 10; i < 20; i++) { sum+=i; } System.out.println(sum); }).start(); new Thread(()->{ int sum = 0; for (int i = 20; i < 30; i++) { sum+=i; } System.out.println(sum); }).start(); new Thread(()->{ int sum = 0; for (int i = 30; i < 40; i++) { sum+=i; } System.out.println(sum); }).start(); new Thread(()->{ int sum = 0; for (int i = 40; i < 50; i++) { sum+=i; } System.out.println(sum); }).start(); new Thread(()->{ int sum = 0; for (int i = 50; i < 60; i++) { sum+=i; } System.out.println(sum); }).start(); new Thread(()->{ int sum = 0; for (int i = 60; i < 70; i++) { sum+=i; } System.out.println(sum); }).start(); new Thread(()->{ int sum = 0; for (int i = 70; i < 80; i++) { sum+=i; } System.out.println(sum); }).start(); new Thread(()->{ int sum = 0; for (int i = 80; i < 90; i++) { sum+=i; } System.out.println(sum); }).start(); new Thread(()->{ int sum = 0; for (int i = 90; i < 100; i++) { sum+=i; } System.out.println(sum); }).start(); } }
运行结果如下:
但是这样有两个问题(1)线程的安全性问题
(2)每个线程的结果没有一个返回值,最终没法把它们汇总起来。*2.所以我们可以采用另外一种方法
2.1采用线程池的方法。我们先创建一个线程池,在里面先放两个线程。
ExecutorService executorService = Executors.newFixedThreadPool(2);
然后他有一个submit方法,返回一个Future 类型的值。
我们可以医用submit的get方法来获取线程的结果。
最后把多个线程的结果相加就可以得到我们想要的结果了。System.out.println(submit.get() + submit1.get());
整体代码如下
package Demo1; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class getSum { public static void main(String[] args) throws Exception{ ExecutorService executorService = Executors.newFixedThreadPool(2); Future<Integer> submit = executorService.submit(() -> { int sum = 0; for (int i = 1; i < 10; i++) { sum += i; } return sum; }); Future<Integer> submit1 = executorService.submit(() -> { int sum = 0; for (int i = 10; i < 20; i++) { sum += i; } return sum; }); System.out.println(submit.get() + submit1.get()); } }
运行结果
-
java 多线程 求和
2021-03-10 09:58:00我编写的一段代码,基本上已经实现多线程求和可是没办法返回每个线程求和之后得出的值我的目的毕竟是求总的和,不是每个线程的和importjava.io.*;classtestthreadextendsThread{intb[...我编写的一段代码,基本上...我编写的一段代码,基本上已经实现多线程求和可是没办法返回每个线程求和之后得出的值我的目的毕竟是求总的和,不是每个线程的和importjava.io.*;classtestthreadextendsThread{intb[...
我编写的一段代码,基本上已经实现多线程求和
可是没办法返回每个线程求和之后得出的值
我的目的毕竟是求总的和,不是每个线程的和
import java.io.*;
class testthread extends Thread
{ int b[]=null;
public testthread(int[] a){b=a;}
public void run()
{int sum=0;
for (int i = 0; i
{
sum=sum+b[i];
}
System.out.println(sum);
}
}
public class thread {
/**
* @param args
*/
public static void main(String args[]) {
// TODO 自动生成方法存根
try{
System.out.print("输入线程数 p(p>=2):");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String A=(String)br.readLine();
int p=Integer.parseInt(A);
System.out.print("输入求和数 n:");
BufferedReader cr=new BufferedReader(new InputStreamReader(System.in));
String B=(String)cr.readLine();
String x[] = B.split(" ") ;
int[] n = new int[x.length] ;
for (int i = 0; i
{
n[i] = new Integer(x[i]).intValue() ;
}
int c=n.length/p;
int a[][]=new int[p][c]; //定义一个多维数组
int b=0;
for(int i=0;i
for(int j=0;j
{a[i][j]=n[b];b++;}
for(int i=0;i
{for(int j=0;j
{System.out.print(a[i][j]+" "); }
System.out.println();
}
for(int i=0;i
new testthread(a[i]).start();
}catch(IOException e){}
}
}
展开
-
java 多线程求和的几种实现方式。
2020-05-27 15:08:32通过多线程计数求和了解synchronized的应用场景,以及其他加锁方式为什么不生效 框架 对象锁和类锁 1、同一时刻只有一个线程执行这段代码 2、最基本的互斥同步手段 3、分类 一共有俩种锁: 1、对象锁 1、同步代码块...前情提要
通过本文你可以收获
- 通过多线程计数求和了解synchronized的应用场景,以及其他加锁方式为什么不生效
- 框架 对象锁和类锁
1、同一时刻只有一个线程执行这段代码
2、最基本的互斥同步手段
3、分类 一共有俩种锁:
1、对象锁
1、同步代码块锁
2、方法锁
3 类锁案例演示与分析:
1、不使用锁 求和会出问题
public class MutilThreadCount implements Runnable{ static int sum = 0; @Override public void run() { //synchronized (this){ for (int i = 0; i < 100000; i++) { sum++; } //} } public static void main(String[] args) throws InterruptedException { MutilThreadCount count = new MutilThreadCount(); Thread t1 = new Thread(count); Thread t2 = new Thread(count); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(sum); } } 预期结果200000 结果小于200000
2、使用volatile也会出问题
public class MutilThreadCount implements Runnable{ static volatile int sum = 0; @Override public void run() { //synchronized (this){ for (int i = 0; i < 100000; i++) { sum++; } //} } public static void main(String[] args) throws InterruptedException { MutilThreadCount count = new MutilThreadCount(); Thread t1 = new Thread(count); Thread t2 = new Thread(count); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(sum); } } 预期结果200000 结果小于200000 volititle有俩个特征: 1、变量对线程是可见的 虽然变量对各个线程是可见的, 但是sum++不是原子的,包含了获取值,自增,赋值 每一个操作都可能被其他线程打断 修改了变量的值 2、防止指令重排 例子就是双重懒加载的单例模式
3、不锁同一个对象 求和会出问题
public class MutilThreadCount implements Runnable{ Object lock1 = new Object(); Object lock2 = new Object(); static int sum = 0; @Override public void run() { synchronized (lock1){ for (int i = 0; i < 100000; i++) { sum=sum+1; } } synchronized (lock2){ for (int i = 0; i < 100000; i++) { sum=sum+1; } } } public static void main(String[] args) throws InterruptedException { MutilThreadCount count = new MutilThreadCount(); Thread t1 = new Thread(count); Thread t2 = new Thread(count); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(sum); } } 预期:400000 结果小于400000 第二个求和循环使用lock1就正确了
4、在方法上使用synchronized 求和正确
public class MutilThreadCount implements Runnable{ static int sum = 0; @Override public void run() { synchronized (this){ for (int i = 0; i < 100000; i++) { sum++; } } } public static void main(String[] args) throws InterruptedException { MutilThreadCount count = new MutilThreadCount(); Thread t1 = new Thread(count); Thread t2 = new Thread(count); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(sum); } } 预期200000结果200000
5、使用synchronized锁类 求和正确(锁类意味着锁住了Class对象 这个类所有的实例都被锁了 所以即使使用lock1和lock2也没问题 )
public class MutilThreadCount implements Runnable{ static int sum = 0; @Override public void run() { synchronized (MutilThreadCount.class){ for (int i = 0; i < 100000; i++) { sum=sum+1; } } } public static void main(String[] args) throws InterruptedException { MutilThreadCount count = new MutilThreadCount(); Thread t1 = new Thread(count); Thread t2 = new Thread(count); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(sum); } } 下面是新建俩个线程对象 但因为是锁的类 ,所以结果也正确,但是如果锁this就不行了 public class MutilThreadCount implements Runnable{ private Object lock1 = new Object(); private Object lock2 = new Object(); static int sum = 0; @Override public void run() { synchronized (MutilThreadCount.class){ for (int i = 0; i < 100000; i++) { sum=sum+1; } } } public static void main(String[] args) throws InterruptedException { MutilThreadCount count1 = new MutilThreadCount(); MutilThreadCount count2 = new MutilThreadCount(); Thread t1 = new Thread(count1); Thread t2 = new Thread(count2); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(sum); } } 预期20000 结果20000
6、使用AtomicInteger(更好的voltitle变量) 求和正确
public class MutilThreadCount implements Runnable{ static AtomicInteger sum = new AtomicInteger(); @Override public void run() { for (int i = 0; i < 100000; i++) { sum.addAndGet(1); } } public static void main(String[] args) throws InterruptedException { MutilThreadCount count = new MutilThreadCount(); Thread t1 = new Thread(count); Thread t2 = new Thread(count); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(sum); } }
7、使用CAS技术(p263) 学懂aqs需要对照着并发包一起学习
8、使用retreentlock
9、使用futuretask来做
voltitle讲解的不错
https://crossoverjie.top/%2F2018%2F03%2F09%2Fvolatile%2F
https://zhuanlan.zhihu.com/p/56191979分析
为什么前面俩种结果不对?
sum++不是一个原子操作
分为三步:
-
读取sum
-
把sum+1
-
把sum写回内存
俩个线程会在这三步中任何一步交替执行,扰乱了sum的值
为什么使用volitile也不行?不是传说中volitile是对线程可见的么?
为什么最后一种执行结果没问题:
在run方法中加了锁关键字就正常输出20000了
锁this也就是意味着给当前对象加了锁
synchronized可以简单的理解为同一时刻只有一个线程执行这段代码
肘后备急
synchronized
-
方法抛出异常 jvm会释放锁
-
synchronized 作用于非static的方法 就是锁了对象 和作用于this一样
作用于static方法就是锁了类,锁了类也就是锁了这个类所有的对象实例,和synchronized(xx.class)作用一样
- 可重入:从外层函数获得锁后,内层函数可以直接获取该锁
同一个方法,不是同一个方法,不是一个类的方法都具有可重入性质,重入意味着获取锁的粒度是线程 不是调用。
可重入原理:
-
不可中断:
-
加锁和释放锁的原理
-
可见性原理:
需要了解Java内存模型 共享变量和线程变量
synchronize释放后 会把变量重新写入主内存,另一个线程也会从主内存中把数据拷贝到线程内存,
但是为什么volitile不行?
-
synchronize缺陷 :
1、释放锁的情况少,试图获得锁不能设定超时,不能中断一个正在试图获取锁的线程
lock更好 可以手动释放锁和设置超时
2、不够灵活 读写锁更灵活
3、无法知道是否成功获取到锁
-
synchronize只会在俩种情况下释放锁:
第一就是执行完成任务,第二是抛出出异常
-
使用注意
锁对象不能为空:因为锁的信息是保存在对象头中的
作用域不要太大,会严重降低效率
避免死锁
-
如何选择synchronize和Lock
尽量不要使用这俩个,可以使用并发包下的
优先使用synchronize 因为代码量少?
如果需要Lock特性 那么就使用Lock
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yFY7nzK7-1590563267129)(/Users/wwh/Library/Application Support/typora-user-images/image-20200303001609889.png)]
-
Java多线程求和 - 一滴水穿石的个人空间 - OSCHINA - 中文开源技术交流社区
2021-02-25 20:30:35import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class SumService {private final Integer nthread;private fina... -
java多线程面试 - 多线程求和
2021-02-25 20:30:33今天面试过程中碰到一个简单的多线程面试题目,竟然一时钻了牛角尖,没有回答上来,结束面试立刻醒悟过来,想想真丢人。面试题目如下:如何多线程计算 1+2+3+……n,其中n是一个很大的数值,不使用直接的求职公式。... -
java面试题-多线程数组求和(CountDownLatch实现)
2021-03-06 02:05:50先对数组进行分段,每段求和,主线程等待所有线程计算完成之后,在执行整体求和。public class CountDownLatchTest {CountDownLatchTest(int count) {this.count = count;executorService = Executors.... -
Java多线程-CyclicBarrier
2022-02-16 17:09:13CyclicBarrier允许一组线程在到达某个栅栏点(common barrier point)互相等待,直到最后一个线程到达栅栏点,栅栏才会打开,处于阻塞状态的线程恢复继续执行。 就比如说我们在打王者的时候,十个人必须全部加载到... -
java面试题-多线程数组求和(CyclicBarrier实现)
2021-03-10 09:58:01CyclicBarrier的作用是拦截多个线程,当所有线程到达指定位置时,在开始往下面执行,否则线程等待。两种构造函数:public CyclicBarrier(int parties)public CyclicBarrier(int parties, ...多线程数组求和,... -
Java----实现多线程数组求和.
2022-04-01 22:59:35import java.util.Arrays; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class test { ... -
Java-多个多线程求和例子以及各种方式的执行效率对比
2017-08-21 18:03:11一、使用Synchronized 同步代码块 ;package thread.worker;...import java.util.concurrent.atomic.AtomicInteger;/** * Created by hl on 2017/8/17. */ public class CountWorker { private int un -
Java并发和多线程2 实现求和
2018-05-23 23:19:42题目是利用多线和求1到20000的和 以8个线程为例 package cn.zhm.day4; public class MutableInteger { int value = 0; MutableInteger(int value) { this.value = value; } } package cn.zhm.day4; /**... -
[Java基础]多线程求和小例子
2021-02-25 20:30:31抛砖引玉吧/*** 多线程求和* @author LIUYONG* 2011-07-31*/public class ThreadTestForSum implements Runnable {static Integer sum = 0;public static void main(String[] args) {for (int i ... -
【Java多线程实战】求和
2018-10-24 17:03:59Java多线程实战-求和 需求:开启五个线程,每个线程对一个给定数值从0开始累加求和。 (1)MyCallable.java package com.storm_02; import java.util.ArrayList; import java.util.Date; import java.util.... -
java用多线程实现累加求和
2021-03-04 08:01:01在楼上基础上大概改一下,增加同步处理。public class Test extends Thread {static int n = 0;private int startNum = 0 ;public Test (int sn){this.startNum = sn ;}public static synchronized void addSum (int... -
多线程求和计算
2021-09-25 10:16:11多线程求和计算: 实现Callable接口 package jess.day06; import java.util.concurrent.Callable; /** * @author Jess * @date 2021/9/25 */ /** * 实现Callable接口 */ public class UseCallable ... -
Java并发和多线程2:3种方式实现数组求和
2017-06-18 17:24:00样例1:单线程样例2:多线程。同步求和(假设没有计算完毕。会堵塞)样例3:多线程。异步求和(先累加已经完毕的计算结果)样例1-代码package cn.fansunion.executorservice; public class BasicCaculator { ... -
java多线程性能浅析
2021-02-28 14:04:07今天看见je上一帖,对于上亿数据求和的算法,采用多线程到底快还是慢,我认为需要按情况而定。1.单核,无IO,网络等资源操作情况下结果:多线程比单线程理论上要慢原因:多线程启动线程需要消耗cpu资源,多线程只是... -
Java多线程—继承Thread类实现求和
2021-03-09 09:13:32public class And extends Thread{private long start;private long end;private long sum=0;public And(long start,long end){super();this.start=start;this.end=end;}public void run(){for(long i=start;...