Java 一个线程需要2秒,10个线程需要16-18秒。为什么?
我的每个线程睡眠时间为2000毫秒,我有10个这样的线程,所以我预计总睡眠时间至少为20秒,但只有16-18秒。对不起,如果我问的是已经问过的问题。以下是我目前掌握的情况:Java 一个线程需要2秒,10个线程需要16-18秒。为什么?,java,multithreading,executorservice,Java,Multithreading,Executorservice,我的每个线程睡眠时间为2000毫秒,我有10个这样的线程,所以我预计总睡眠时间至少为20秒,但只有16-18秒。对不起,如果我问的是已经问过的问题。以下是我目前掌握的情况: import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUni
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MyThreadPoolApp {
public static void main(String[] args) {
long execTime = System.currentTimeMillis();
CountDownLatch latch = new CountDownLatch(1);
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executor.submit(new Task());
}
System.out.println("threads submitted and waiting execution");
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
}
execTime = System.currentTimeMillis() - execTime;
System.out.format("%d threads finished execution \n",Task.getCount());
System.out.println("thread time : " + Task.getTime());
System.out.println("main time : " + execTime);
}
}
我的输出:
threads submitted and waiting execution
10 threads finished execution
thread time : 18001
main time : 2020
因为您正在处理各种线程对totalTime的并发更新 试试这个:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MyThreadPoolApp {
public static void main(String[] args) {
long execTime = System.currentTimeMillis();
CountDownLatch latch = new CountDownLatch(1);
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executor.submit(new Task());
}
System.out.println("threads submitted and waiting execution");
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
}
execTime = System.currentTimeMillis() - execTime;
System.out.format("%d threads finished execution \n",Task.getCount());
System.out.println("thread time : " + Task.getTime());
System.out.println("main time : " + execTime);
}
}
class Task implements Runnable {
private static long totalTime;
private static int count;
public static long getTime(){
synchronized(Task.class){
return totalTime;
}
}
private static void addTime(long time){
synchronized(Task.class){
totalTime = totalTime + time;
}
}
public static int getCount(){ return count; }
public void run() {
count++;
long startTime = System.currentTimeMillis();
try {
Thread.sleep(2000);
addTime(System.currentTimeMillis() - startTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.concurrent.CountDownLatch;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
公共类MyThreadPoolApp{
公共静态void main(字符串[]args){
long execTime=System.currentTimeMillis();
CountDownLatch闩锁=新的CountDownLatch(1);
ExecutorService executor=Executors.newFixedThreadPool(10);
对于(int i=0;i<10;i++){
执行者。提交(新任务());
}
System.out.println(“提交并等待执行的线程”);
executor.shutdown();
试一试{
执行人。等待终止(1,时间单位。分钟);
}捕捉(中断异常e){
}
execTime=System.currentTimeMillis()-execTime;
System.out.format(“%d个线程已完成执行\n”,Task.getCount());
System.out.println(“线程时间:+Task.getTime());
System.out.println(“主时间:+execTime”);
}
}
类任务实现可运行{
私有静态长时间;
私有静态整数计数;
公共静态长getTime(){
已同步(Task.class){
返回总时间;
}
}
专用静态无效添加时间(长时间){
已同步(Task.class){
总时间=总时间+时间;
}
}
公共静态int getCount(){return count;}
公开募捐{
计数++;
long startTime=System.currentTimeMillis();
试一试{
《睡眠》(2000年);
addTime(System.currentTimeMillis()-startTime);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
编辑
如您所愿,在run()方法中同步:
import java.util.concurrent.CountDownLatch;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
公共类MyThreadPoolApp{
公共静态void main(字符串[]args){
long execTime=System.currentTimeMillis();
CountDownLatch闩锁=新的CountDownLatch(1);
ExecutorService executor=Executors.newFixedThreadPool(10);
对于(int i=0;i<10;i++){
执行者。提交(新任务());
}
System.out.println(“提交并等待执行的线程”);
executor.shutdown();
试一试{
执行人。等待终止(1,时间单位。分钟);
}捕捉(中断异常e){
}
execTime=System.currentTimeMillis()-execTime;
System.out.format(“%d个线程已完成执行\n”,Task.getCount());
System.out.println(“线程时间:+Task.getTime());
System.out.println(“主时间:+execTime”);
}
}
类任务实现可运行{
私有静态长时间;
私有静态整数计数;
公共静态长getTime(){
已同步(Task.class){
返回总时间;
}
}
公共静态int getCount(){return count;}
公开募捐{
计数++;
long startTime=System.currentTimeMillis();
试一试{
《睡眠》(2000年);
已同步(Task.class){
totalTime+=System.currentTimeMillis()-startTime;
}
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
您正在捕获InterruptedException
而没有对其执行任何操作。你认为那里可能出了什么问题,导致睡眠中断吗?说得对。我没想过。我试试看@Michael不,那里什么都没有..如果将synchronized放在run()方法中呢?将保存另外两个同步方法,不是吗?是的,您可以将同步块放入run()方法中以更新总时间!但仅在Task.class上同步,因为您正在更新类变量。
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MyThreadPoolApp {
public static void main(String[] args) {
long execTime = System.currentTimeMillis();
CountDownLatch latch = new CountDownLatch(1);
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executor.submit(new Task());
}
System.out.println("threads submitted and waiting execution");
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
}
execTime = System.currentTimeMillis() - execTime;
System.out.format("%d threads finished execution \n",Task.getCount());
System.out.println("thread time : " + Task.getTime());
System.out.println("main time : " + execTime);
}
}
class Task implements Runnable {
private static long totalTime;
private static int count;
public static long getTime(){
synchronized(Task.class){
return totalTime;
}
}
private static void addTime(long time){
synchronized(Task.class){
totalTime = totalTime + time;
}
}
public static int getCount(){ return count; }
public void run() {
count++;
long startTime = System.currentTimeMillis();
try {
Thread.sleep(2000);
addTime(System.currentTimeMillis() - startTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MyThreadPoolApp {
public static void main(String[] args) {
long execTime = System.currentTimeMillis();
CountDownLatch latch = new CountDownLatch(1);
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executor.submit(new Task());
}
System.out.println("threads submitted and waiting execution");
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
}
execTime = System.currentTimeMillis() - execTime;
System.out.format("%d threads finished execution \n",Task.getCount());
System.out.println("thread time : " + Task.getTime());
System.out.println("main time : " + execTime);
}
}
class Task implements Runnable {
private static long totalTime;
private static int count;
public static long getTime(){
synchronized(Task.class){
return totalTime;
}
}
public static int getCount(){ return count; }
public void run() {
count++;
long startTime = System.currentTimeMillis();
try {
Thread.sleep(2000);
synchronized(Task.class){
totalTime += System.currentTimeMillis() - startTime;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}