对于每个对象的创建,我希望它可以通过标识符唯一地访问。我正在使用递增的静态值来跟踪已创建的对象数,并且每次构造一个新对象时,我使其标识符等于count + 1(并递增计数)。我遇到的问题是同步不起作用。以下是代码的简化版本:
public static final Hashtable MODULES = new Hashtable();
private static final Object countLock = new Object();
private static int count = 0;
private final String identifier;
private final String name;
public Class(String name) {
this.identifier = String.valueOf(incrementCount());
this.name = name;
MODULES.put(identifier, name);
}
private static int incrementCount() {
synchronized (countLock) {
return ++count;
}
}
现在当我用这个测试时(不可否认,但不可否认,但确定它有效):
for (int x = 0; x < 100; x++) {
new Thread(new Runnable() {
@Override
public void run() {
Class m = new Class("Name");
}
}).start();
}
System.out.println(Module.MODULES.size());
我的输出从60分到100分。显然我不希望那种不可靠性。一个动荡的领域会在这里运作吗(我尝试过相同的结果)我不确定如何确保每个class
对象都有不同的标识符。欢迎任何解决方案。
注意:出于特定的实现原因,我无法访问java.util.concurrent。
答案 0 :(得分:3)
你的锁工作正常,但问题是不同的。您正在通过新的Thread
初始化每个对象。 当线程在后台运行时,主线程会立即打印计数。在两者之间设置适当的延迟,您将看到正确的计数。
public static void main(String[] args) throws InterruptedException{
for (int x = 0; x < 100; x++) {
new Thread(new Runnable() {
@Override
public void run() {
Counter m = new Counter("Name");
}
}).start();
}
Thread.sleep(1000);//put a delay
System.out.println(MODULES.size());
}
答案 1 :(得分:1)
试试这个:
for (int x = 0; x < 100; x++) {
new Thread(new Runnable() {
@Override
public void run() {
Class m = new Class("Name");
}
}).start();
}
Thread.sleep(500);
System.out.println(Module.MODULES.size());
答案 2 :(得分:0)
您正在打印未同步的哈希表的大小。 在语句MODULES.put(identifier,name);
之前添加一个synchronized语句synchronized (MODULES) {
MODULES.put(identifier, name);
}
它对我有用。
答案 3 :(得分:0)
以下是我在代码中看到的问题:语句Class m = new Class("Name");
位于run()
函数中,而不是Runnable
的实现<的构造函数中/ em>在您的代码中。
如果我必须编写类似的代码,我会这样写:
public class ModuleTest {
public static void main(String[] args) {
for (int x = 0; x < 100; x++) {
new Thread(new Runnable() {
{
Module m = new Module("Name");
}
@Override
public void run() {
// do something
}
}).start();
}
System.out.println(Module.MODULES.size());
}
}
查看上面的语句Module m = new Module("Name");
的位置。它不在run()
函数中,因为调用run()
时会调用start()
。该声明位于未命名的大括号{}
之间,在您的代码中构建Runnable
的匿名实现时调用该大括号。{/ p>
要完成上面的代码,这里是Module
类:
import java.util.Hashtable;
public class Module {
public static final Hashtable MODULES = new Hashtable();
private static final Object countLock = new Object();
private static int count = 0;
private final String identifier;
private final String name;
public Module(String name) {
this.identifier = String.valueOf(incrementCount());
this.name = name;
MODULES.put(identifier, name);
}
private synchronized static int incrementCount() {
return ++count;
}
}