Java如何用同步块来保护静态变量?

SuperMiner 2007-04-21 04:52:01
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();
}
}
...全文
1230 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
SuperMiner 2007-04-29
  • 打赏
  • 举报
回复
按楼上的方法是可以解决的,我也试了另外一种解决方法:把j由int改成Integer,然后需要访问它时对它加锁,也就是synchronized(j),这样就可以了。
ylncepu 2007-04-21
  • 打赏
  • 举报
回复
你对 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
SuperMiner 2007-04-21
  • 打赏
  • 举报
回复
忘了把输出结果贴出来了,不好意思

a
syned J=444

j=446
syned J=446
b
c
1
2
3

一直都是这个结果。:(

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧