多线程中的一点疑问

ifvlr 2013-09-18 11:18:17
小弟在遍历int类型的所有数时,对于多线程,产生了点疑问
先看代码
单线程:

public class TestNumber {

public int test(int i){
return 0;//让传入的所有int类型数都返回0
}

public void method1(){
long start = System.currentTimeMillis();
int min = Integer.MIN_VALUE;
int max = Integer.MAX_VALUE;
boolean flag = true; //记录初始值flag
for(int i=min; i<max; i++){
if(test(i) != 0){
flag = false; //如果返回值不是0则改变为true;
break;
}
}
System.out.println(flag);
long end = System.currentTimeMillis();
System.out.println("方法运行时间:"+(end-start));
}


public static void main(String[] args) {
TestNumber tn = new TestNumber();
tn.method1();
}
}

方法的某次运行结果为
true
方法运行时间:8329

多线程:


public class TestThreadNumber implements Runnable{

public int test(int i){
return 0;
}

@Override
public void run() {
long start = System.currentTimeMillis();
int min = Integer.MIN_VALUE;
int max = Integer.MAX_VALUE;
boolean flag = true;
for(int i=1; i<max; i++){
if(test(i) != 0){
flag = false;
break;
}
}
System.out.println(flag);
long end = System.currentTimeMillis();
System.out.println("线程1运行时间:"+(end-start));
}

public void test(){
int min = Integer.MIN_VALUE;
int max = Integer.MAX_VALUE;
boolean flag = true;
for(int i=min; i<0; i++){
if(test(i) != 0){
flag = false;
break;
}
}
System.out.println(flag);
}

public static void main(String[] args) {
long start = System.currentTimeMillis();
TestThreadNumber ttn = new TestThreadNumber();
Thread t = new Thread(ttn);
t.start(); //启动线程1
ttn.test();//主线程调用test方法
long end = System.currentTimeMillis();
System.out.println("主线程运行时间:"+(end-start));
}
}


方法的某次运行结果为
true
线程1运行时间:3304
true
主线程运行时间:3332


我觉得像遍历所有int类型的数,从小到大一条线程足矣,因为cpu在每个时间点上只能处理一个指令,那么从小到大遍历,应该是一件很简单的事。如果我用多线程,那么cpu反要再两条线程上不停的切换,每个时间点还是只能处理一个指令。 可是实际结果却是多线程明显快了很多,并且速度还不止一倍,这是为什么呢?这个和双核的CPU有关系么?

顺便问个小问题,怎么测试所有线程都运行完所花费的时间啊,我在main方法中写记录时间,只能记录主线程的时间吧。。
...全文
499 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
踩踩一哥 2013-09-23
  • 打赏
  • 举报
回复
可以再通俗点,假设你电脑是单核,相当于你和你朋友轮流扔球,你俩扔球的速度取决于扔的慢的那个人,如果有一个人扔的很慢,扔球的速度肯定是比你一个人扔的慢的。但是如果你有很多球要仍,只有你有一个人扔,那么,你的体力就相当于cpu消耗,你会越扔越慢。这时候如果是两个人扔,你们俩消耗的体力有可能只是你一个人时候的一半,所以比你一个人扔球要快。
踩踩一哥 2013-09-22
  • 打赏
  • 举报
回复
引用 18 楼 ifvlr 的回复:
[quote=引用 17 楼 qq864680621 的回复:] for(int i=min; i<max; i++){ if(test(i) != 0){ flag = false; //如果返回值不是0则改变为true; break; } 帅哥,你这里是循环min到max,而在多线程中循环数只是这里一半的数量。min到0,1到max。所以速度肯定要比单线程快至少两倍。 例如你开了某一个程序,那这个程序占用了你CPU百分之10左右,那多余的百分之90咋办?那如果是多线程,当你在开启第二个程序的时候,另外的百分之90就会被拿来使用,这样以便提高CPU的使用率。 所以多线程就是把那 90%的空闲 模拟成另一块物理CPU,来提高你的工作效率,这样10%和90%互不干涉,不会因为堆积在一起的数据而降低CPU的效率! 多线程只是共享一块数据,并不是切换内存,就是说,两个线程轮流操作一块数据。相当于是两个人一起干一个活,当然速度要快不少了。
非常感谢你的回答,我的问题是卡在了这里。 多线程是分为了两部分,但是多线程的工作量并没有减少,只是两条线程在跑。而cpu每一个时间点只能做一件事情,那为什么多线程要快呢?而且这种遍历应该不存在阻塞情况吧。 我是这么理解的。比如我有很多球要放入一个容器中,而容器每次只能进去一个球,一条线程跑相当于我是一个人往里面扔球。多线程相当于我找了个朋友帮我扔,但是每次还是只能进去一个球。。两个人切换着扔,感觉时间应该要得更多。因为在切换 这是我对多线程的疑问,根据程序运行的结果,我知道我上面的理解是错误的。但是不知道多线程到底是怎样的。或者说是因为cpu是双核的?单核cpu是我说的上面这种情况么?[/quote] 如果是单核,两个线程是相互竞争的,是切换时间片,但是这个时间是很小的。一般在20ms左右,因此如果只是开两个线程,这个时间可以忽略。如果电脑是双核的,那么就相当于你和你朋友一起往里面扔球。两个人各干各的事情,不存在切换
简单随心 2013-09-22
  • 打赏
  • 举报
回复
时间片轮转,一台电脑不可能就你一个程序在跑。竞争者还有很多,当使用多个线程的时候,是否抢到CPU的概率也就变大了呢?
housuhang 2013-09-20
  • 打赏
  • 举报
回复
看不懂看不懂
steely_chen 2013-09-20
  • 打赏
  • 举报
回复
引用 18 楼 ifvlr 的回复:
[quote=引用 17 楼 qq864680621 的回复:] for(int i=min; i<max; i++){ if(test(i) != 0){ flag = false; //如果返回值不是0则改变为true; break; } 帅哥,你这里是循环min到max,而在多线程中循环数只是这里一半的数量。min到0,1到max。所以速度肯定要比单线程快至少两倍。 例如你开了某一个程序,那这个程序占用了你CPU百分之10左右,那多余的百分之90咋办?那如果是多线程,当你在开启第二个程序的时候,另外的百分之90就会被拿来使用,这样以便提高CPU的使用率。 所以多线程就是把那 90%的空闲 模拟成另一块物理CPU,来提高你的工作效率,这样10%和90%互不干涉,不会因为堆积在一起的数据而降低CPU的效率! 多线程只是共享一块数据,并不是切换内存,就是说,两个线程轮流操作一块数据。相当于是两个人一起干一个活,当然速度要快不少了。
非常感谢你的回答,我的问题是卡在了这里。 多线程是分为了两部分,但是多线程的工作量并没有减少,只是两条线程在跑。而cpu每一个时间点只能做一件事情,那为什么多线程要快呢?而且这种遍历应该不存在阻塞情况吧。 我是这么理解的。比如我有很多球要放入一个容器中,而容器每次只能进去一个球,一条线程跑相当于我是一个人往里面扔球。多线程相当于我找了个朋友帮我扔,但是每次还是只能进去一个球。。两个人切换着扔,感觉时间应该要得更多。因为在切换 这是我对多线程的疑问,根据程序运行的结果,我知道我上面的理解是错误的。但是不知道多线程到底是怎样的。或者说是因为cpu是双核的?单核cpu是我说的上面这种情况么?[/quote] 应该两个人不需要切换着扔,你的电脑是多核的,两个人是可以同时扔的。
steely_chen 2013-09-18
  • 打赏
  • 举报
回复
引用 12 楼 yousteely 的回复:
我想你的测试是在同一台机子上运行。 我在自己的机子上分别测试了两个案例,先运行第一个得到时间是119,再运行多线程的分别是2和3,接着再运行第一个单线程得到的时间是2或1。然后无论运行哪一个案例时间都在1-3之间。至于为什么还待大牛出来解释一下。
因为运行时间太快,我测试的时候是将三个循环都是从min到max
ifvlr 2013-09-18
  • 打赏
  • 举报
回复
各位可以把for循环里面的代码都去掉来测试。。 各位如果没有看懂我的意思的话我就这么说描述一下。 用单线程:从int的最小值遍历到int的最大值,时间大概8秒到9秒 这是我的电脑上; 用多线程:主线程从int的最小值遍历到0,用线程1从1遍历到int的最大值。两个线程都是3秒左右,因为线程1和主线程是同步进行的,所以两个方法运行完所花的时间大概也就3秒。多线程的方式明显比单线程快了2倍还多。。 我的疑问是 因为cpu在每个时间点只能处理一条指令,既然只是做遍历操作,单线程只是从小到大速度应该很快的。多线程还要再两条线程之间切换,也把int类型的数全部遍历到了。反而时间少了很多。不明白这是为什么。。。
steely_chen 2013-09-18
  • 打赏
  • 举报
回复
我想你的测试是在同一台机子上运行。 我在自己的机子上分别测试了两个案例,先运行第一个得到时间是119,再运行多线程的分别是2和3,接着再运行第一个单线程得到的时间是2或1。然后无论运行哪一个案例时间都在1-3之间。至于为什么还待大牛出来解释一下。
ifvlr 2013-09-18
  • 打赏
  • 举报
回复
引用 6 楼 xxhhbb1538 的回复:
[quote=引用 4 楼 xxhhbb1538 的回复:] [quote=引用 3 楼 xxhhbb1538 的回复:] 我也好奇,谁来给个解释啊
我擦,你上下两段程序的循环条件不一样 第二个是 for(int i=min; i<0; i++),小于0啊,第一个是 for(int i=min; i<max; i++),小于max啊, 这两个可是天壤之别,差太多了吧,难怪时间相差那么多。[/quote] 不好意思我看错了。主线程从min到0,子线程从1到max。两个加起来时间跟第一个程序不一样。 好吧,求高人来解答[/quote] 代码是没有错误的,单线程的代码是从int的最小值遍历到int的最大值,至于那个return 0其实无关紧要,只是一个测试用的,让他永久返回0而已。 多线程的代码:主线程从int的最小值遍历到0,线程1从 1遍历到int的最大值。
ifvlr 2013-09-18
  • 打赏
  • 举报
回复
引用 7 楼 hjw506848887 的回复:
看了半天不知所以然,坐等答案吧!
您可以把代码拷贝到您机器上测试一下。 多线程的的两个值几乎是同时打印的,意思运行完这个程序的时间只是最大的那个而并非是把两个时间加起来。。 但是单线程的遍历那个时间就相对有点慢了。
ifvlr 2013-09-18
  • 打赏
  • 举报
回复
引用 2 楼 healer_kx 的回复:
看不懂你的代码。你的代码有错误没?
代码是没有错误的,单线程的代码是从int的最小值遍历到int的最大值,至于那个return 0其实无关紧要,只是一个测试用的,让他永久返回0而已。 多线程的代码:主线程从int的最小值遍历到0,线程1从 1遍历到int的最大值。
naniandenuoruo 2013-09-18
  • 打赏
  • 举报
回复
4楼说的有道理,你可以吧min、和max分别输出,看看两者的max - min的差别
  • 打赏
  • 举报
回复
看了半天不知所以然,坐等答案吧!
  • 打赏
  • 举报
回复
引用 4 楼 xxhhbb1538 的回复:
[quote=引用 3 楼 xxhhbb1538 的回复:] 我也好奇,谁来给个解释啊
我擦,你上下两段程序的循环条件不一样 第二个是 for(int i=min; i<0; i++),小于0啊,第一个是 for(int i=min; i<max; i++),小于max啊, 这两个可是天壤之别,差太多了吧,难怪时间相差那么多。[/quote] 不好意思我看错了。主线程从min到0,子线程从1到max。两个加起来时间跟第一个程序不一样。 好吧,求高人来解答
ghostkngiht 2013-09-18
  • 打赏
  • 举报
回复
两个程序占用cpu的时间应该是一样的,但是程序运行的时间会不一样,多线程可能会更有效的利用cpu,减少cpu的空闲时间。上面是我的猜测,仅供参考。
  • 打赏
  • 举报
回复
引用 3 楼 xxhhbb1538 的回复:
我也好奇,谁来给个解释啊
我擦,你上下两段程序的循环条件不一样 第二个是 for(int i=min; i<0; i++),小于0啊,第一个是 for(int i=min; i<max; i++),小于max啊, 这两个可是天壤之别,差太多了吧,难怪时间相差那么多。
  • 打赏
  • 举报
回复
我也好奇,谁来给个解释啊
healer_kx 2013-09-18
  • 打赏
  • 举报
回复
看不懂你的代码。你的代码有错误没?
ganshenml 2013-09-18
  • 打赏
  • 举报
回复
坐等答案!
ifvlr 2013-09-18
  • 打赏
  • 举报
回复
引用 17 楼 qq864680621 的回复:
for(int i=min; i<max; i++){ if(test(i) != 0){ flag = false; //如果返回值不是0则改变为true; break; } 帅哥,你这里是循环min到max,而在多线程中循环数只是这里一半的数量。min到0,1到max。所以速度肯定要比单线程快至少两倍。 例如你开了某一个程序,那这个程序占用了你CPU百分之10左右,那多余的百分之90咋办?那如果是多线程,当你在开启第二个程序的时候,另外的百分之90就会被拿来使用,这样以便提高CPU的使用率。 所以多线程就是把那 90%的空闲 模拟成另一块物理CPU,来提高你的工作效率,这样10%和90%互不干涉,不会因为堆积在一起的数据而降低CPU的效率! 多线程只是共享一块数据,并不是切换内存,就是说,两个线程轮流操作一块数据。相当于是两个人一起干一个活,当然速度要快不少了。
非常感谢你的回答,我的问题是卡在了这里。 多线程是分为了两部分,但是多线程的工作量并没有减少,只是两条线程在跑。而cpu每一个时间点只能做一件事情,那为什么多线程要快呢?而且这种遍历应该不存在阻塞情况吧。 我是这么理解的。比如我有很多球要放入一个容器中,而容器每次只能进去一个球,一条线程跑相当于我是一个人往里面扔球。多线程相当于我找了个朋友帮我扔,但是每次还是只能进去一个球。。两个人切换着扔,感觉时间应该要得更多。因为在切换 这是我对多线程的疑问,根据程序运行的结果,我知道我上面的理解是错误的。但是不知道多线程到底是怎样的。或者说是因为cpu是双核的?单核cpu是我说的上面这种情况么?
加载更多回复(3)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧