读写共享线程变量

时间:2013-07-17 08:42:21

标签: java multithreading synchronized

首先,我是线程和共享变量的新手。所以请和我好心;-)

我正在上一个名为Routing的班级。该类接收并处理消息。如果消息的类型为A,则Routing - 对象应将其传递给实现ASender接口的Runnable对象。如果邮件的类型为B,则Routing - 类应将其传递给BSender对象。

但是ASenderBSender对象有共同的变量,应存储在Routing - 对象中。

我现在的想法是在Routing - Object和getter / setter中将变量声明为synchronized / volatile。

这是同步代码的正确方法吗?或者缺少什么?

编辑:添加了基本代码的想法。

RoutingClass

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;
}
}

ASender Class

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 个答案:

答案 0 :(得分:1)

一些意见:

  1. Hashtable是一个线程安全的实现,您不需要其他“同步”关键字,请参阅thisthis以获取更多信息
  2. 避免耦合,尝试使用接口或将哈希表传递给发件人,有关详细信息,请参阅this
  3. 根据发件人的数量,您可能希望使用ConcurrentHashMap,这会极大地提高效果,请参阅ConcurrentHashMap and Hashtable in JavaJava theory and practice: Concurrent collections classes
  4. 这将结束类似......:

    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)
        }
    
    }