Java如何用同步块来保护静态变量?
Java怎么样才能保护类的静态变量呢?
我在同步块中用synchronized(Babble.class)来给Babble类加锁,可是类变量j还是在中途被另一个线程更改了,怎么才能在这个过程中保护静态变量j呢?
public class Babble {
private static synchronized void say(String s){
System.out.println(s);
}
static int j=444;
public static void main(String[] args) {
Thread letters=new Thread(){
public void run(){
synchronized(Babble.class){
//此处加在Babble类上的锁不能保护static int j,为什么?
try{
say( "a ");
System.out.println( "syned J= "+j);
Thread.sleep(1000);
System.out.println( "syned J= "+j);
//此时发现j已经被另一个线程改变了
Thread.sleep(1000);
say( "b ");
Thread.sleep(1000);
say( "c ");
Thread.sleep(1000);
}
catch(InterruptedException e)
{}
}
}
};
Thread numbers=new Thread(){
public void run(){
try{
++Babble.j;
Babble bb=new Babble();
System.out.println();
System.out.println( "j= "+(++Babble.j));
say( "1 ");
Thread.sleep(1000);
say( "2 ");
Thread.sleep(1000);
say( "3 ");
Thread.sleep(1000);
}
catch(InterruptedException e)
{}
}
};
letters.start();
numbers.start();
}
}
[解决办法]
你对 say() 加锁,没问题,当你 Synchronized(Babble.class)时,表示 Babble中的say方法会被加锁(因为 say() 的修饰符是synchronized) 这时,letters启动,只有letters线程才能访问
say()方法, 但 j 并没有 加锁(因为 j是static public , 只要是Babble对象,都可以访问)
你之所以会有疑问,是因为你对 Java的 synchronized加锁机制 并没有深入的理解
对一个对象加锁, 只是对对象中声明synchronized的方法获得锁的权限,那些非synchronized
方法其他线程仍然可以访问,这才是对对象加锁
解决方案: 个人想法
将 j 作成 private ,并用 getJ()/setJ()对它封装, 并在 getJ()/setJ()上加 synchronized