从Java中的两个线程访问共享变量

我正在用Java构建一个应用程序,它需要从两个类的实例访问Hashtable并扩展线程。我已经在两个类中的一个中声明了Hashtable。当我尝试从其中一个类访问Hashtable内容时,我总是得到null。另一个类可以毫无问题地访问内容。我认为这是并发控制的问题。由于这些是不同类的线程,因此我们无法使用同步方法。有没有办法让Hashtable可以从两个类的线程访问? 以下是我的应用程序代码的一些部分 这是存储HashMap的类:
public class DataStore {
public Map ChatWindows ;
public DataStore()
{
    ChatWindows = new ConcurrentHashMap();
}
public synchronized void putWindow(String with,ChatWindow t)
{
    ChatWindows.put(with,t);
    notifyAll();
}
public synchronized ChatWindow getWindow(String with)
{
    notifyAll();
    return (ChatWindow)ChatWindows.get(with);
}
public synchronized void ChatWindowOpen(chatClient cc,String with,String msg)
    {
       //    chatWith = with;
        ChatWindow t;
        System.out.println(with);
            t = getWindow(with);
           if(t == null)
           {
               t = new ChatWindow(cc,with,msg);
         //      th = new Thread(t);
               putWindow(with, t);
         //      th.start();
           }
           else
           {
              t.setVisible(true);

            }
}
}
两个访问'ChatWindows'HashMap的类
public class chatClient extends javax.swing.JFrame implements 

Runnable,ListSelectionListener,MouseListener,WindowListener{

  static String LoginName,chatWith,msgToChatWindow;
    Thread listThread=null,th,chatListen;
static  Socket soc;
static  DataOutputStream dout,dout1;
static  DataInputStream din,din1;
        DefaultListModel listModel;

        ChatWindow t;

    public DataStore ds;
/** Creates new form chatClient */
public chatClient(Login l,DataStore ds) {
    listModel = new DefaultListModel();
    initComponents();
    clientList.addListSelectionListener(this);

     clientList.addMouseListener(this);
     addWindowListener(this);
      this.LoginName=l.loginName;

        soc = l.soc2;
        din = l.din2;
        dout = l.dout2;
        dout1 = l.dout1;
        din1 = l.din1;
        super.setTitle(LoginName);

        listThread = new Thread(this);
        listThread.start();
        this.ds = ds;

}
.
.
.
.
public void mouseClicked(MouseEvent e)
{
    chatWith = (String)clientList.getSelectedValue();
    ds.ChatWindowOpen(this,chatWith,"");
}
这个类也有run()方法,但是它不使用HashMap。这个类能够正确访问'ChatWindows'。'ChatListenThread'类无法正确访问HashMap的内容。
public class ChatListenThread implements Runnable{

DataOutputStream dout1;
DataInputStream din1;
public static chatClient cc;
public static ChatWindow t;
public DataStore ds;
    public ChatListenThread(Login l,DataStore ds)
    {
        din1 = l.din1;
        dout1= l.dout1;
        this.ds = ds;
    }
.
.
.
.
public void run(){
   while(true)
   {
       try{
                    String msgFromServer=new String();
                    msgFromServer = din1.readUTF();
                    StringTokenizer st=new StringTokenizer(msgFromServer);
        String msgFrom=st.nextToken();
        String MsgType=st.nextToken();
                    String msg = "";
                   while(st.hasMoreTokens())
        {
            msg=msg+" " +st.nextToken();
        }

                    ds.ChatWindowOpen(cc,msgFrom,msg);                       

       }
       catch(IOException e)
       {
            System.out.println("Read failed");

       }
   }
} }     
已邀请:
这是可能的。看一下两个线程之间安全地共享数据。     
哦,我无法使用你的代码,因为我不明白,我看到的是你想要的东西是这样的: 用
JTabbedPane
创建一个空的
JFrame
并启动一个连接到
Socket
的线程 当输入进入插座时,创建一个
ChatPanel
(~
JTextArea
)并将其添加到其中一个选项卡 将
ChatPanel
添加到处理来自“
from
”的消息的
Map
将消息传递给新创建的
ChatPanel
所以我这样做了,我发布下面的代码!希望你能用它! 如果你想测试它,首先启动
TestChatServer
(下面的代码),然后启动
ChatSupervisor
。 这是客户端的代码
public class ChatSupervisor extends JFrame implements Runnable {

    JTabbedPane tabs = new JTabbedPane();
    Map<String, ChatPanel> chats = new ConcurrentHashMap<String, ChatPanel>();

    public ChatSupervisor() {
        super("Test Chat");
        add(tabs, BorderLayout.CENTER);

        new Thread(this).start();
    }

    public void run() {
        Socket sock = null;
        try {
            sock = new Socket("localhost", 32134);

            Scanner s = new Scanner(sock.getInputStream());
            while (true) {

                String from = s.next();
                String type = s.next();
                String message = s.nextLine();

                getChat(from).incomingMessage(type, message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (sock != null) try { sock.close(); } catch (IOException e) {}
        }
    }

    public ChatPanel getChat(String from) {
        if (!chats.containsKey(from))
            chats.put(from, new ChatPanel(from));

        return chats.get(from);
    }

    public static void main(String[] args) {
        ChatSupervisor cs = new ChatSupervisor();
        cs.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cs.setSize(400, 300);
        cs.setVisible(true);
    }

    class ChatPanel extends JTextArea {
        public ChatPanel(final String from) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    tabs.addTab(from, ChatPanel.this);
                }
            });
        }
        public void incomingMessage(final String type, final String message) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    append("[" + type + "]" + message);
                    append("n");
                }
            });
        }
    }
}
这是测试服务器的代码:
public class TestChatServer {
    public static void main(String[] args) throws Exception {
        Socket s = new ServerSocket(32134).accept();
        System.out.println("connected");
        PrintWriter p = new PrintWriter(s.getOutputStream());
        while (true) {

            p.println("hello info Hello World!");
            p.flush();
            Thread.sleep(1000);

            for (int i = 0; i < 10; i++) {
                p.println("test" + i + " warn Testing for testing " + i);
                p.flush();
                Thread.sleep(100);
            }
        }
    }
}
    

要回复问题请先登录注册