多线程充分的利用CPU多核资源
1.单个线程,串行的,完成20亿次自增
public class TestDemo1 {
//1.单个线程,串行的,完成20亿次自增
private static final long COUNT = 20_0000_0000;
private static void serial(){
//需要把方法执行的时间记录下来
long beg = System.currentTimeMillis(); //记录当前的毫秒级时间戳
int a=0;
for (long i = 0;i<COUNT;i++){
a++;
}
a = 0;
for (long i = 0;i<COUNT;i++){
a++;
}
long end = System.currentTimeMillis();
System.out.println("单线程消耗的时间" + (end - beg) +"ms");
}
public static void main(String[] args) {
serial();
}
}
消耗了1063ms
2.两个线程,并发的,完成20亿次自增
错误代码:
public class TestDemo1 {
//2.两个线程,并发的,完成20亿次自增
private static final long COUNT = 20_0000_0000;
private static void concurrency(){
long beg = System.currentTimeMillis();
Thread t1 = new Thread(()->{
int a=0;
for (long i = 0;i<COUNT;i++){
a++;
}
});
Thread t2 = new Thread(()->{
int a=0;
for (long i = 0;i<COUNT;i++){
a++;
}
});
t1.start(); //创建线程
t2.start();
long end = System.currentTimeMillis();
System.out.println("多线程消耗的时间" + (end-beg) +"ms");
}
public static void main(String[] args) {
concurrency();
}
}
这段代码错误的原因是因为,不仅有t1、t2线程,还有main函数,总共三个线程。不等t1,t2执行完,main线程就往下走了,于是结束计时。正确的做法是等到t1,t2都执行完,才停止计时。
需要加上join方法:
join是等待线程结束(等待线程把自己的run方法执行完)
在主线程中调用t1.join,就是让main线程等待t1执行完。
public class TestDemo1 {
//2.两个线程,并发的,完成20亿次自增
private static final long COUNT = 20_0000_0000;
private static void concurrency(){
long beg = System.currentTimeMillis();
Thread t1 = new Thread(()->{
int a=0;
for (long i = 0;i<COUNT;i++){
a++;
}
});
Thread t2 = new Thread(()->{
int a=0;
for (long i = 0;i<COUNT;i++){
a++;
}
});
t1.start(); //创建线程
t2.start();
try {
t1.join(); //join方法,并引入异常处理
t2.join();
}catch (InterruptedException e){
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("多线程消耗的时间" + (end-beg) +"ms");
}
public static void main(String[] args) throws InterruptedException{
concurrency();
}
}
消耗了617ms
3、注意点
两个线程不是单纯的将单线程时间缩短一半,
1、创建线程自身,也是有开销的
扫描二维码关注公众号,回复:
14818559 查看本文章
2、两个线程在CPU上不一定是纯并行,也可能是并发,一部分时间里是并行的,一部分是并发的
3、线程的调度,也是有开销的。(当前场景中,开销应该是非常小的)
4、 多线程的使用场景
1、在CPU密集型场景
代码中大部分的工作,都是在使用CPU进行运算(如上述案例的++),使用多线程,就可以更好的利用CPU多核计算资源,如人工智能相关的场景,计算量很大。
2、在IO密集型场景
如读写磁盘,读写网卡等。这些场景里,需要花很大的时间进行等待,像这些IO操作,都是几乎不消耗CPU就能完成快速的数据的操作。既然CPU在摸鱼,就可以给他找点活干,因此可以使用多线程,避免中央处理器过于闲置。