System.out.println()为什么会影响到多线程? 多线程 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 同问,ExecutorService起到阻塞的作用? 受到启发,用new Thread的方式试了下,发现没问题;看来是因为 ExecutorService导致的,但它是怎么做到的呢,希望有大拿能给出解答! 受到启发,用new Thread的方式试了下,发现没问题;看来是因为 ExecutorService导致的,但它是怎么做到的呢,希望有大拿能给出解答!我也用new Thread的方法试了一下,结果跟ExecutorService的一样,应该不是ExecutorService的问题 这里并非因为阻塞了,而是因为两个++val执行所需要的时间太小了,而造成了你的一种错觉。你在++val中间加上一行try{ Thread.sleep(100); }catch(Exception e){}很快你就会发现最终只有一个线程在跑了,其它9个都会在很短的时间内结束掉。 最好先试一下楼主的代码再说话你说了之后,我特意运行了一下,没有发现有阻塞啊。你所说的阻塞是在哪。把这句注释掉结果就不一样了System.out.println(val); 最好先试一下楼主的代码再说话你说了之后,我特意运行了一下,没有发现有阻塞啊。你所说的阻塞是在哪。把这句注释掉结果就不一样了System.out.println(val); 我还以为你们说的是什么。我第一个回复是没错的。并非是因为println阻塞,而是因为println所消耗的时间远远超过++val的时间,而造成的错觉。只需在两个++中间sleep一个时间段,就能够很轻易的看到效果了。 最好先试一下楼主的代码再说话你说了之后,我特意运行了一下,没有发现有阻塞啊。你所说的阻塞是在哪。把这句注释掉结果就不一样了System.out.println(val); 我还以为你们说的是什么。我第一个回复是没错的。并非是因为println阻塞,而是因为println所消耗的时间远远超过++val的时间,而造成的错觉。只需在两个++中间sleep一个时间段,就能够很轻易的看到效果了。可能是跟System.out 获得的流有关。 又是一个讨论离题的帖子,查下源代码就知道原因了。public void println(int x) { synchronized (this) { print(x); newLine(); }} 其实并没有阻止并发,将程序改成这样private static int val = 0; private int i = 10; @Override public void run() { while (i-- > 0) { ++val; ++val; System.out.println(Thread.currentThread().getId() + ":" + val); // 在我电脑上测试,此处添加打印输出似乎防止了并发的产生,为什么? if (val % 2 != 0) { System.out.println(val + " not event!"); return; } } }得到的结果是10:1010:6810:7010:7210:7410:7610:7810:810:8010:8411:11611:11811:12011:12211:12411:2611:2811:3011:3411:812:15212:15612:16812:17012:17412:17812:18212:18612:19012:9013:11413:12613:12813:13013:13213:16213:3213:3613:3813:4014:2214:5014:5214:5414:5614:5814:6014:6214:6414:6615:10015:10215:10415:10615:10815:11015:11215:4615:9615:9816:13616:13816:14016:14216:14416:14616:14816:15016:15816:9217:15417:17217:18017:18817:19217:19417:19617:19817:20017:828:1348:1608:1648:1668:1768:1848:528:868:908:949:129:149:169:189:209:249:429:469:489:8可以看出线程间还是交叉运行的,val++的操作都执行完了,我觉得可能是每个线程都在等待IO的调用,所以获得数都是偶数,这个应该跟线程与IO调用关系有关 Hi,我做了个实验,我发现没有打印方法的代码更容易出现奇数退出程序。但并不是说有System的代码不会出现奇数。请用调试模式启动System打印的代码,在not event处打上断点。立即会得到断点进入,并且完成线程退出。这可以说明这条语句没有造成妨碍并发,只是使得并发更难发生。至于为什么更难,我也不太清楚。 要的就是你的答案!out对象加的同步锁与楼主描述的状况并无实际关联。其实并没有阻止并发,将程序改成这样private static int val = 0; private int i = 10; @Override public void run() { while (i-- > 0) { ++val; ++val; System.out.println(Thread.currentThread().getId() + ":" + val); // 在我电脑上测试,此处添加打印输出似乎防止了并发的产生,为什么? if (val % 2 != 0) { System.out.println(val + " not event!"); return; } } }得到的结果是10:1010:6810:7010:7210:7410:7610:7810:810:8010:8411:11611:11811:12011:12211:12411:2611:2811:3011:3411:812:15212:15612:16812:17012:17412:17812:18212:18612:19012:9013:11413:12613:12813:13013:13213:16213:3213:3613:3813:4014:2214:5014:5214:5414:5614:5814:6014:6214:6414:6615:10015:10215:10415:10615:10815:11015:11215:4615:9615:9816:13616:13816:14016:14216:14416:14616:14816:15016:15816:9217:15417:17217:18017:18817:19217:19417:19617:19817:20017:828:1348:1608:1648:1668:1768:1848:528:868:908:949:129:149:169:189:209:249:429:469:489:8可以看出线程间还是交叉运行的,val++的操作都执行完了,我觉得可能是每个线程都在等待IO的调用,所以获得数都是偶数,这个应该跟线程与IO调用关系有关我认为13楼说的是对的。 其实并没有阻止并发,将程序改成这样private static int val = 0; private int i = 10; @Override public void run() { while (i-- > 0) { ++val; ++val; System.out.println(Thread.currentThread().getId() + ":" + val); // 在我电脑上测试,此处添加打印输出似乎防止了并发的产生,为什么? if (val % 2 != 0) { System.out.println(val + " not event!"); return; } } }得到的结果是9:8可以看出线程间还是交叉运行的,val++的操作都执行完了,我觉得可能是每个线程都在等待IO的调用,所以获得数都是偶数,这个应该跟线程与IO调用关系有关能说的更详细点吗?线程与IO调用有什么关系呢? System.out这个获得的都是同一个对象,synchronized (this)用这个锁就能保证异步了,不会同步执行。多写点多线程例子,就能很容易理解。 System.out这个获得的都是同一个对象,synchronized (this)用这个锁就能保证异步了,不会同步执行。多写点多线程例子,就能很容易理解。public void run() { while (true) { ++val; ++val; // System.out.println(val); synchronized (System.out) { } if (val % 2 != 0) { System.out.println(val + " not event!"); return; } } }我可以这么理解吗?还是不行啊! 理解是可以这么理解的,但是实际情况还有事情需求考虑。synchronized (System.out) {}这里一定要有耗时操作,时间必须超过new10次的时间 EvenCheckerEasy(),因为按你这样写,第一个start走到synchronized (System.out)时,如果有一个EvenCheckerEasy刚刚开始start,第一个判断val % 2 != 0前,正好这个个EvenCheckerEasy刚做一次++val,这个线程还没有开始竞争锁操作,第一个线程正好val变成单数了。你可以用这样代码注释下下前后对比。public void run() { while (true) { ++val; ++val; synchronized (System.out) {//注释掉这行测试 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } }//注释掉这行测试 if (val % 2 != 0) { System.out.println(val + " not event!"); return; } } }当原理很明确的时候,出现奇怪现象,你只要逐行看看你的代码,你自己就能想清楚为什么出现这个情况。 理解是可以这么理解的,但是实际情况还有事情需求考虑。synchronized (System.out) {}这里一定要有耗时操作,时间必须超过new10次的时间 EvenCheckerEasy(),因为按你这样写,第一个start走到synchronized (System.out)时,如果有一个EvenCheckerEasy刚刚开始start,第一个判断val % 2 != 0前,正好这个个EvenCheckerEasy刚做一次++val,这个线程还没有开始竞争锁操作,第一个线程正好val变成单数了。你可以用这样代码注释下下前后对比。public void run() { while (true) { ++val; ++val; synchronized (System.out) {//注释掉这行测试 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } }//注释掉这行测试 if (val % 2 != 0) { System.out.println(val + " not event!"); return; } } }当原理很明确的时候,出现奇怪现象,你只要逐行看看你的代码,你自己就能想清楚为什么出现这个情况。good,解释的很清楚! 怎么把jar文件转换成为exe 容器方面的题目 struts 打开新画面问题 如何通过服务器端程序,删除客户端IE7临时文件? 读xml问题 一个java编程题目,大家帮帮忙 请帮我看看这道笔试题吧。 高手来看看!关于计算代码中注释行算法的问题。 Java与条码打印 java获取文件的绝对路径后将。转换成/ 同时调用不同包同名类同名方法,怎么实现? Java io 中关于System.in的一个小问题
我也用new Thread的方法试了一下,结果跟ExecutorService的一样,应该不是ExecutorService的问题
你在++val中间加上一行try{ Thread.sleep(100); }catch(Exception e){}很快你就会发现最终只有一个线程在跑了,其它9个都会在很短的时间内结束掉。
把这句注释掉结果就不一样了
System.out.println(val);
把这句注释掉结果就不一样了
System.out.println(val);
我还以为你们说的是什么。我第一个回复是没错的。并非是因为println阻塞,而是因为println所消耗的时间远远超过++val的时间,而造成的错觉。只需在两个++中间sleep一个时间段,就能够很轻易的看到效果了。
把这句注释掉结果就不一样了
System.out.println(val);
我还以为你们说的是什么。我第一个回复是没错的。并非是因为println阻塞,而是因为println所消耗的时间远远超过++val的时间,而造成的错觉。只需在两个++中间sleep一个时间段,就能够很轻易的看到效果了。可能是跟System.out 获得的流有关。
synchronized (this) {
print(x);
newLine();
}
}
private static int val = 0;
private int i = 10; @Override
public void run() {
while (i-- > 0) {
++val;
++val;
System.out.println(Thread.currentThread().getId() + ":" + val); // 在我电脑上测试,此处添加打印输出似乎防止了并发的产生,为什么?
if (val % 2 != 0) {
System.out.println(val + " not event!");
return;
}
}
}
得到的结果是
10:10
10:68
10:70
10:72
10:74
10:76
10:78
10:8
10:80
10:84
11:116
11:118
11:120
11:122
11:124
11:26
11:28
11:30
11:34
11:8
12:152
12:156
12:168
12:170
12:174
12:178
12:182
12:186
12:190
12:90
13:114
13:126
13:128
13:130
13:132
13:162
13:32
13:36
13:38
13:40
14:22
14:50
14:52
14:54
14:56
14:58
14:60
14:62
14:64
14:66
15:100
15:102
15:104
15:106
15:108
15:110
15:112
15:46
15:96
15:98
16:136
16:138
16:140
16:142
16:144
16:146
16:148
16:150
16:158
16:92
17:154
17:172
17:180
17:188
17:192
17:194
17:196
17:198
17:200
17:82
8:134
8:160
8:164
8:166
8:176
8:184
8:52
8:86
8:90
8:94
9:12
9:14
9:16
9:18
9:20
9:24
9:42
9:46
9:48
9:8
可以看出线程间还是交叉运行的,val++的操作都执行完了,我觉得可能是每个线程都在等待IO的调用,所以获得数都是偶数,这个应该跟线程与IO调用关系有关
请用调试模式启动System打印的代码,在not event处打上断点。立即会得到断点进入,并且完成线程退出。这可以说明这条语句没有造成妨碍并发,只是使得并发更难发生。至于为什么更难,我也不太清楚。
out对象加的同步锁与楼主描述的状况并无实际关联。其实并没有阻止并发,将程序改成这样
private static int val = 0;
private int i = 10; @Override
public void run() {
while (i-- > 0) {
++val;
++val;
System.out.println(Thread.currentThread().getId() + ":" + val); // 在我电脑上测试,此处添加打印输出似乎防止了并发的产生,为什么?
if (val % 2 != 0) {
System.out.println(val + " not event!");
return;
}
}
}
得到的结果是
10:10
10:68
10:70
10:72
10:74
10:76
10:78
10:8
10:80
10:84
11:116
11:118
11:120
11:122
11:124
11:26
11:28
11:30
11:34
11:8
12:152
12:156
12:168
12:170
12:174
12:178
12:182
12:186
12:190
12:90
13:114
13:126
13:128
13:130
13:132
13:162
13:32
13:36
13:38
13:40
14:22
14:50
14:52
14:54
14:56
14:58
14:60
14:62
14:64
14:66
15:100
15:102
15:104
15:106
15:108
15:110
15:112
15:46
15:96
15:98
16:136
16:138
16:140
16:142
16:144
16:146
16:148
16:150
16:158
16:92
17:154
17:172
17:180
17:188
17:192
17:194
17:196
17:198
17:200
17:82
8:134
8:160
8:164
8:166
8:176
8:184
8:52
8:86
8:90
8:94
9:12
9:14
9:16
9:18
9:20
9:24
9:42
9:46
9:48
9:8
可以看出线程间还是交叉运行的,val++的操作都执行完了,我觉得可能是每个线程都在等待IO的调用,所以获得数都是偶数,这个应该跟线程与IO调用关系有关我认为13楼说的是对的。
private static int val = 0;
private int i = 10; @Override
public void run() {
while (i-- > 0) {
++val;
++val;
System.out.println(Thread.currentThread().getId() + ":" + val); // 在我电脑上测试,此处添加打印输出似乎防止了并发的产生,为什么?
if (val % 2 != 0) {
System.out.println(val + " not event!");
return;
}
}
}
得到的结果是9:8
可以看出线程间还是交叉运行的,val++的操作都执行完了,我觉得可能是每个线程都在等待IO的调用,所以获得数都是偶数,这个应该跟线程与IO调用关系有关能说的更详细点吗?线程与IO调用有什么关系呢?
多写点多线程例子,就能很容易理解。
多写点多线程例子,就能很容易理解。
public void run() {
while (true) {
++val;
++val;
// System.out.println(val);
synchronized (System.out) {
}
if (val % 2 != 0) {
System.out.println(val + " not event!");
return;
}
}
}
我可以这么理解吗?还是不行啊!
synchronized (System.out) {}这里一定要有耗时操作,时间必须超过new10次的时间 EvenCheckerEasy(),因为按你这样写,第一个start走到synchronized (System.out)时,如果有一个EvenCheckerEasy刚刚开始start,第一个判断val % 2 != 0前,正好这个个EvenCheckerEasy刚做一次++val,这个线程还没有开始竞争锁操作,第一个线程正好val变成单数了。
你可以用这样代码注释下下前后对比。public void run() {
while (true) {
++val;
++val;
synchronized (System.out) {//注释掉这行测试
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}//注释掉这行测试
if (val % 2 != 0) {
System.out.println(val + " not event!");
return;
}
}
}
当原理很明确的时候,出现奇怪现象,你只要逐行看看你的代码,你自己就能想清楚为什么出现这个情况。
synchronized (System.out) {}这里一定要有耗时操作,时间必须超过new10次的时间 EvenCheckerEasy(),因为按你这样写,第一个start走到synchronized (System.out)时,如果有一个EvenCheckerEasy刚刚开始start,第一个判断val % 2 != 0前,正好这个个EvenCheckerEasy刚做一次++val,这个线程还没有开始竞争锁操作,第一个线程正好val变成单数了。
你可以用这样代码注释下下前后对比。public void run() {
while (true) {
++val;
++val;
synchronized (System.out) {//注释掉这行测试
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}//注释掉这行测试
if (val % 2 != 0) {
System.out.println(val + " not event!");
return;
}
}
}
当原理很明确的时候,出现奇怪现象,你只要逐行看看你的代码,你自己就能想清楚为什么出现这个情况。good,解释的很清楚!