首先,我对线程和共享变量不熟悉。所以请善待我;-)
我正在上一个叫Routing
的课。此类接收和处理消息。如果消息类型为A
,则Routing
-对象应将其传递给实现Runnable
接口的ASender
对象。如果消息的类型为B
,则Routing
-Class应将其传递给BSender
对象。
但是ASender
和BSender
对象有共同的变量,这些变量应该存储在Routing
-对象中。
我现在的想法是在Routing
-Object和getter/setter中声明变量为synchronized/voile。
这是同步代码的正确方式吗?还是什么东西不见了?
编辑:添加了基本的代码思想。
路由类
public class Routing {
private synchronized Hashtable<Long, HashSet<String>> reverseLookup;
private ASender asender;
private BSender bsender;
public Routing() {
//Constructor work to be done here..
reverseLookup = new Hashtable<Long, HashSet<String>>();
}
public void notify(TopicEvent event) {
if (event.getMessage() instanceof AMessage) {
asender = new ASender(this, event.getMessage())
} else if (event.getMessage() instanceof BMessage) {
bsender = new BSender(this, event.getMessage())
}
}
public synchronized void setReverseLookup(long l, Hashset<String> set) {
reverseLookup.put(l, set);
}
public synchronized Hashtable<Long, Hashset<String>> getReverseLookup() {
return reverseLookup;
}
}
A投标人等级
public class ASender implements Runnable {
private Routing routing;
private RoutingMessage routingMessage;
public ASender(Routing r, RoutingMessage rm) {
routing = r;
routingMessage = rm;
this.run();
}
public void run() {
handleMessage();
}
private void handleMessage() {
// do some stuff and extract data from the routing message object
routing.setReverseLookup(somethingToSet)
}
}
一些评论:
- Hashtable是一个线程安全的实现,您不需要另一个"synchronized"关键字。有关详细信息,请参阅this和this
- 避免耦合,尝试使用接口或将哈希表传递给发送者,有关详细信息,请参阅
- 根据发送方的数量,您可能希望使用ConcurrentHashMap,它大大提高了性能,请参阅Java和Java理论与实践中的ConcurrentHashMap和Hashtable:并发集合类
这会得出这样的结论:
public interface IRoutingHandling {
void writeMessage(Long key, HashSet<String> value);
}
public class Routing implements IRoutingHandling {
private final Hashtable<Long, HashSet<String>> reverseLookup;
private ASender asender;
private BSender bsender;
public Routing() {
//Constructor work to be done here..
reverseLookup = new Hashtable<Long, HashSet<String>>();
}
public void notify(TopicEvent event) {
if (event.getMessage() instanceof AMessage) {
asender = new ASender(this, event.getMessage())
} else if (event.getMessage() instanceof BMessage) {
bsender = new BSender(this, event.getMessage())
}
}
@Override
public void writeMessage(Long key, HashSet<String> value) {
reverseLookup.put(key, value);
}
}
public class ASender implements Runnable {
private IRoutingHandling _routingHandling;
public ASender(IRoutingHandling r, RoutingMessage rm) {
_routingHandling = r;
routingMessage = rm;
this.run();
}
public void run() {
handleMessage();
}
private void handleMessage() {
// do some stuff and extract data from the routing message object
_routingHandling.writeMessage(somethingToSetAsKey, somethingToSetAsValue)
}
}