读取和写入共享线程变量



首先,我对线程和共享变量不熟悉。所以请善待我;-)

我正在上一个叫Routing的课。此类接收和处理消息。如果消息类型为A,则Routing-对象应将其传递给实现Runnable接口的ASender对象。如果消息的类型为B,则Routing-Class应将其传递给BSender对象。

但是ASenderBSender对象有共同的变量,这些变量应该存储在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)
}
}

一些评论:

  1. Hashtable是一个线程安全的实现,您不需要另一个"synchronized"关键字。有关详细信息,请参阅this和this
  2. 避免耦合,尝试使用接口或将哈希表传递给发送者,有关详细信息,请参阅
  3. 根据发送方的数量,您可能希望使用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)
    }
}

最新更新