解决方案 »
- 可以对FlowLayout中划分的窗体各部分调整大小吗?
- 求高手解答!
- java中如何把utf-8的汉子转为gbk,我用的jdk1.6。
- 如何通过一个字符串的值得到对应的类型
- 关于在IBM上看到的一个synchronized问题
- 新人请高手帮我看看,冒泡排序,数组的问题?
- 关于嵌套synchronized块中资源的释放
- JComboBox的问题,可以让下拉出来的列表显示两列吗?
- 各位大虾:大家好,请问哪里能下载到<<JAVA与模式>>电子工业出版社 这本书呢?我想要一份完整的,请各位帮帮忙!
- jmx的几个基础问题
- 同时调用不同包同名类同名方法,怎么实现?
- 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,解释的很清楚!