我正在尝试设置同步和非同步方法之间的区别..我尝试了以下代码
class Counter {
private int counter = 10;
public int getCounter() {
return counter;
}
public synchronized void doIncrementAndDecrement() {
counter++;
keepBusy(500);
counter--;
}
public void keepBusy(int howLong) { // (D)
long curr = System.currentTimeMillis();
while (System.currentTimeMillis() < curr + howLong)
;
}
}
class MyCounterThread extends Thread {
Counter c;
public MyCounterThread(Counter c, String name) {
// TODO Auto-generated constructor stub
super(name);
this.c = c;
start();
}
@Override
public void run() {
for (;;) {
c.doIncrementAndDecrement();
sleepForSometime();
System.out.println(c.getCounter());
}
}
public void sleepForSometime() { // (D)
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class UnSynchronizedExapmle {
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
MyCounterThread t1 = new MyCounterThread(c, "A");
MyCounterThread t2 = new MyCounterThread(c, "B");
MyCounterThread t3 = new MyCounterThread(c, "C");
}
}
所以上面我有 doIncrementAndDecrement()同步方法..
所以我预计每次计数器的值应为10。但这不会发生我有输出就像
10
10
11
10
10
10
10
11
10
10
11
10
11
11
10
10
11
10
11
10
10
10
11
10
10
11
10
所以请帮助我为什么会发生这种情况..或者用于解释同步和异步方法之间区别的任何博客/文章
答案 0 :(得分:5)
您的getCounter()方法未同步。因此,即使一个线程可能正在锁定该方法,另一个线程仍然可以访问并打印您的计数器变量
答案 1 :(得分:2)
您的代码不会同步 getCounter 方法,以便 System.out.println 可以输出计数器的内部。方法上的同步与已同步(此)相同。
答案 2 :(得分:1)
...如果我在keepBusy()方法中编写Thread.sleep()会有什么不同...因为输出在两种情况下都是完全不同的。
它的作用是让keepBusy()
花费很长时间,因此会使getCounter()
等待很长时间。
输出的差异是由于同步阻止getCounter()
在增量状态下“看到”计数器。
我的意思是什么区别使得Thread.sleep()和keepBusy()方法中的上述while循环在线程调度或锁定方面做了..
没有区别。
对于记录,真正的程序使用keepBusy()
之类的方法睡在同步方法或块中是不明智的。 sleep
会导致尝试在目标对象上同步的任何其他线程被阻止......并且这可能会降低应用程序的实际并行度。