这两天在学习多线程并发,写了一个例子
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class CountDownLatchTest {
private static int poolSize = 2;
private static CountDownLatch countDown = new CountDownLatch(poolSize);
public static void main(String [] args) {
long startTime = System.currentTimeMillis();
System.out.println("主线程start use:" + startTime);
Callable<String> call1 = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000);
countDown.countDown();
System.out.println(Thread.currentThread().getName()+" user time "+(System.currentTimeMillis()-startTime));
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
};
Callable<String> call2 = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000);
countDown.countDown();
System.out.println(Thread.currentThread().getName()+" user time "+(System.currentTimeMillis()-startTime));
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
};
FutureTask<String> ft1 = new FutureTask<String>(call1);
FutureTask<String> ft2 = new FutureTask<String>(call2);
ExecutorService executor = Executors.newFixedThreadPool(poolSize);
executor.execute(ft1);
executor.execute(ft2);
try {
countDown.await();
System.out.println(poolSize+"个子线程已经执行完毕");
System.out.println("主线程end use:" + (System.currentTimeMillis()-startTime));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果:
主线程start use:1546396254696
pool-1-thread-2 user time 1011
2个子线程已经执行完毕
pool-1-thread-1 user time 1011
主线程end use:1011
恩,完美,执行效率挺高的
--------------------------------------------------------------------------------------
然后突然想到,如果poolSize设置成1呢,
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class CountDownLatchTest {
private static int poolSize = 1;
private static CountDownLatch countDown = new CountDownLatch(poolSize);
public static void main(String [] args) {
long startTime = System.currentTimeMillis();
System.out.println("主线程start use:" + startTime);
Callable<String> call1 = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000);
countDown.countDown();
System.out.println(Thread.currentThread().getName()+" user time "+(System.currentTimeMillis()-startTime));
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
};
Callable<String> call2 = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000);
countDown.countDown();
System.out.println(Thread.currentThread().getName()+" user time "+(System.currentTimeMillis()-startTime));
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
};
FutureTask<String> ft1 = new FutureTask<String>(call1);
FutureTask<String> ft2 = new FutureTask<String>(call2);
ExecutorService executor = Executors.newFixedThreadPool(poolSize);
executor.execute(ft1);
executor.execute(ft2);
try {
countDown.await();
System.out.println(poolSize+"个子线程已经执行完毕");
System.out.println("主线程end use:" + (System.currentTimeMillis()-startTime));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果:
主线程start use:1546396057514
pool-1-thread-1 user time 1011
1个子线程已经执行完毕
主线程end use:1011
pool-1-thread-1 user time 2011
这,执行时间翻倍了啊,
----------------------------------------------------------------------------------
然后我又给加了个Callable,代码就不上了,直接放结果
执行结果:
主线程start use:1546396574511
pool-1-thread-1 user time 1028
1个子线程已经执行完毕
主线程end use:1028
pool-1-thread-1 user time 2029
pool-1-thread-1 user time 3039
执行时间再次增加。。。。而且都是thread-1
结论:多线程情况下,如果有m个线程,线程池大小为n,poolSize = m<n?m:n,会先创建poolSize个线程,然后创建剩余线程,并且线程编号重新开始排序
是不是真的是这样呢,所有我又写了一个,1000个线程,但是每次会重新创建一次线程池,且size为1
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class HighConcurrenceTest {
private static int poolSize = 1000;
private static CountDownLatch countDown = new CountDownLatch(poolSize);
public static void main(String [] args) {
List<FutureTask<String>> list = new ArrayList<FutureTask<String>>();
long startTime = System.currentTimeMillis();
System.out.println("主线程start use:" + startTime);
for(int i = 0;i<poolSize;i++) {
Callable<String> call = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000);
countDown.countDown();
System.out.println(Thread.currentThread().getName()+" user time "+(System.currentTimeMillis()-startTime));
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
};
FutureTask<String> future = new FutureTask<String>(call);
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(future);
}
try {
countDown.await();
System.out.println("end use:" + (System.currentTimeMillis()-startTime));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果:
主线程start use:1546398444063
pool-84-thread-1 user time 1002
pool-82-thread-1 user time 1002
pool-86-thread-1 user time 1002
...
...
pool-832-thread-1 user time 1050
end use:1066
pool-834-thread-1 user time 1050
...
pool-823-thread-1 user time 1050
pool-826-thread-1 user time 1050
pool-827-thread-1 user time 1050
上边的程序,虽然有1000个线程,由于每次往线程池放一个线程,所以执行时间并没有受影响
--------------------------------------------------------------------------------------------------------------------------------
当然,实验不能就这样得结论,再测试一个
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class HighConcurrenceTest {
private static int poolSize = 1000;
private static CountDownLatch countDown = new CountDownLatch(poolSize);
public static void main(String [] args) {
List<FutureTask<String>> list = new ArrayList<FutureTask<String>>();
long startTime = System.currentTimeMillis();
System.out.println("主线程start use:" + startTime);
for(int i = 0;i<poolSize;i++) {
Callable<String> call1 = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000);
countDown.countDown();
System.out.println(Thread.currentThread().getName()+" user time "+(System.currentTimeMillis()-startTime));
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
};
Callable<String> call2 = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000);
countDown.countDown();
System.out.println(Thread.currentThread().getName()+" user time "+(System.currentTimeMillis()-startTime));
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
};
FutureTask<String> future1 = new FutureTask<String>(call1);
FutureTask<String> future2 = new FutureTask<String>(call2);
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(future1);
executor.execute(future2);
}
try {
countDown.await();
System.out.println("end use:" + (System.currentTimeMillis()-startTime));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果:
主线程start use:1546398807709
pool-3-thread-1 user time 1013
pool-1-thread-1 user time 1013
...
...
pool-729-thread-1 user time 1080
end use:1080
pool-731-thread-1 user time 1080
...
pool-569-thread-1 user time 2112
pool-570-thread-1 user time 2112
pool-574-thread-1 user time 2112
-----------------------------------------------------------------------------------------------------------------------------
ok,这些可以得结论啦,撒花撒花。。。。
结论1:多线程情况下,如果有m个线程,线程池大小为n,poolSize = m<n?m:n,会先创建poolSize个线程,然后创建剩余线程,并且线程编号重新开始排序
结论2:多线程情况下,如果有m个线程,线程池大小为n,poolSize = m<n?m:n,会先创建poolSize个线程,然后创建剩余线程,并且线程编号重新开始排序,线程执行时间也会相应增加
如有理解错误,欢迎讨论