java并发(二)对象的共享-可见性


public class NoVisibility {
private static boolean ready;

private static int number;

private static class ReaderThread extends Thread{
public void run(){
while(!ready){
Thread.yield();
System.out.println(number);
}
}//end run()
}//end Class ReaderThread

public static void main(String[] args){
new ReaderThread().start();
number = 42;
ready = true;
}
}


NoVisibility可能不会打印任何值,因为读线程可能永远看不到ready的值。一种更奇怪的现象是,NoVisibility可能会输出0,因为读线程可能看到了写入的ready的值,但是却没有看到之后写入的number的值。只要有数据在多个线程之间共享,就应该使用正确的同步。

public class MutableInteger {

private int value;

public int getValue() {
return value;
}

public void setValue(int value) {
this.value = value;
}


}

MutableInteger不是线程安全的,因为get和set都是在没有同步的情况下访问value的。

public class SynchronizedInteger {

@GuardedBy("this")private int value;

public synchronized int getValue() {
return value;
}

public synchronized void setValue(int value) {
this.value = value;
}


}

SynchronizedInteger中,通过对get和set方法进行同步,可以使MutableInteger成为一个线程安全类。仅对set方法进行同步是不够的。另外,在多线程程序中使用共享且可变的long和double等类型的变量也是不安全的,可以使用volatile来声明,或者用锁保护起来(加锁机制既可以确保可见性又可以确保原子性,而volatile变量只嗯呢该确保可见性)。

你可能感兴趣的:(java,技术)