BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #41503同步于 2015/6/9
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

synchronized怎么不起用呢?

cuter
2015/6/9镜像同步20 回复
package Syncr; public class Main { public static void main(String[] args) { Counter counter=new Counter(); Thread t1=new Thread(new TestThread(counter,1)); Thread t2=new Thread(new TestThread(counter,2)); t1.start(); t2.start(); } } class TestThread implements Runnable{ private Counter counter=null; private int tag=0; public TestThread(Counter counter,int tag) { // TODO Auto-generated constructor stub this.counter=counter; this.tag=tag; } @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<10000;i++){ counter.increment(); System.out.println(tag+": "+counter.value()); } } } class Counter { private static int c=0; public synchronized void increment(){ c++; } public synchronized void decrement(){ c--; } public synchronized int value(){ return c; } } 输出结果: .... 2: 15858 2: 15859 1: 15813 1: 15861 .... 难道不是连续的吗?
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
icyfox机器人#1 · 2015/6/9
因为是两个不同对象的?
cuter机器人#2 · 2015/6/9
不是吧,都是基本上连续的: 2: 10 2: 11 2: 12 2: 13 2: 14 2: 15 2: 16 2: 17 2: 18 2: 19 2: 20 2: 21 2: 22 2: 23 2: 24 2: 25 1: 26 1: 27 1: 28 1: 29 1: 31 1: 32 1: 33 1: 34 1: 35 1: 36 【 在 icyfox 的大作中提到: 】 : 因为是两个不同对象的?
lkasdolka2机器人#3 · 2015/6/9
虽然increment()和value()两个方法都是同步的,但是在TestThread的run方法中,这两个方法并没有在一个同步块中,所以可能出现一个线程实例访问increment,另一个线程实例访问value方法。 run()可以改成: public void run() { for(int i=0;i<10000;i++){ synchronized (TestThread.class) { counter.increment(); System.out.println(tag+": "+counter.value()); } } } 我也刚开始学这些,如有错误,请指出~
nuanyangyang机器人#4 · 2015/6/9
synchronized可以保证到最后肯定加了20000次,最后的value应该是20000。 但在increment()和value()之间,值可能会改变,而且两个线程可以交替执行,所以你打出来的值没有理由是连续的。
cuter机器人#5 · 2015/6/9
有点懂了,thx! 【 在 lkasdolka2 的大作中提到: 】 : 虽然increment()和value()两个方法都是同步的,但是在TestThread的run方法中,这两个方法并没有在一个同步块中,所以可能出现一个线程实例访问increment,另一个线程实例访问value方法。 : run()可以改成: : [code=java] : ...................
cuter机器人#6 · 2015/6/9
多谢,看来我理解错了。 【 在 nuanyangyang 的大作中提到: 】 : synchronized可以保证到最后肯定加了20000次,最后的value应该是20000。 但在increment()和value()之间,值可能会改变,而且两个线程可以交替执行,所以你打出来的值没有理由是连续的。
beiyourener机器人#7 · 2015/6/10
?何解 【 在 icyfox 的大作中提到: 】 : 因为是两个不同对象的?
beiyourener机器人#8 · 2015/6/10
一个线程访问increase方法,另一个线程还能访问value方法? 【 在 lkasdolka2 的大作中提到: 】 : 虽然increment()和value()两个方法都是同步的,但是在TestThread的run方法中,这两个方法并没有在一个同步块中,所以可能出现一个线程实例访问increment,另一个线程实例访问value方法。 : run()可以改成: : [code=java] : ...................
beiyourener机器人#9 · 2015/6/10
我这边测试了下,tag和值确实都是乱序的 但是我的疑问是tag乱序没有问题,因为increase和pring方法不是原子的 但是根据同步的“线程可见性”我觉得起码值应该是顺序的,因为increase++后,不管是线程一还是线程二 进入value方法后看到的c应该是最新值,但结果却不是这样,望指点一二 【 在 nuanyangyang 的大作中提到: 】 : synchronized可以保证到最后肯定加了20000次,最后的value应该是20000。 但在increment()和value()之间,值可能会改变,而且两个线程可以交替执行,所以你打出来的值没有理由是连续的。