此为 thinking in java 的一个例子.
如果一个线程类,在run方法里掉一个方法r(),对一个 int i 的变量做两次自加操作 , 有一个方法叫 getValue() , 取得int i的值.
main方法里,启动线程,同时一个死循环,一直取getValue();
如果getValue()取得的值是奇数则退出.
当对方法r()做 synchronized的时候,是会取得奇数的,
当且并当 getValue() 做 synchronized时,就取不到奇数了.
个人理解的 synchronized是监视器只能当前线程在执行synchronized的方法.(蹩脚的个人描述,但同网上的一个理解)
假定 A 为自增线程 ,B 为main线程.
猜测:情况 r()为 synchronized , getValue() 不为synchronized,
A自增了1次,切换到线程B,此时会取得奇数.
那么 synchronized 的方法执行时也是可以轮询到其他的线程的,这貌似也不违反并发的原则.因为另外一个线程并未执行此方法.
那为什么将 getValue() 设为 synchronized 时,就不会出现奇数的情况了呢?
帖代码:
[code="java"]
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerTest implements Runnable
{
private AtomicInteger ai = new AtomicInteger(0);
private Integer i = 0;
@Override
public void run()
{
// this.ai.addAndGet(2);
r();
}
private synchronized void r(){
while (true)
{
this.i++;
this.i++;
}
}
public synchronized int getValue()
{
// return ai.get();
return i;
}
public static void main(String[] args)
{
ExecutorService es = Executors.newCachedThreadPool();
final AtomicIntegerTest ai = new AtomicIntegerTest();
es.execute(ai);
new Timer().schedule(new TimerTask()
{
@Override
public void run()
{
System.out.println("close");
//System.out.println(ai.getValue());
System.exit(0);
}
}, 5000);
int i;
while (true)
{
i = ai.getValue();
System.out.println("-" + i);
if (i % 2 != 0)
{
System.out.println("--" + i);
System.exit(0);
}
Thread.yield();
}
}
}
[/code]