Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中从两个线程访问共享变量_Java_Multithreading_Class_Shared - Fatal编程技术网

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

在Java中从两个线程访问共享变量,java,multithreading,class,shared,Java,Multithreading,Class,Shared,我正在用Java构建一个应用程序,它需要从两个类和两个扩展线程的实例访问哈希表。我在两个类中的一个类中声明了哈希表。当我试图从其中一个类访问哈希表内容时,我总是得到null。另一个类可以毫无问题地访问内容。我认为这是并发控制的问题。因为它们是不同类的线程,所以我们不能使用同步方法。有没有办法让这两个类的线程都可以访问哈希表 下面是我的应用程序代码的一些部分 这是存储HashMap的类: public class DataStore { public Map ChatWindows ; publi

我正在用Java构建一个应用程序,它需要从两个类和两个扩展线程的实例访问哈希表。我在两个类中的一个类中声明了哈希表。当我试图从其中一个类访问哈希表内容时,我总是得到null。另一个类可以毫无问题地访问内容。我认为这是并发控制的问题。因为它们是不同类的线程,所以我们不能使用同步方法。有没有办法让这两个类的线程都可以访问哈希表

下面是我的应用程序代码的一些部分 这是存储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
    ,并启动一个连接到
    套接字的线程
  • 当套接字上出现输入时,创建一个
    ChatPanel
    (~
    JTextArea
    )并将其添加到一个选项卡中
  • 聊天面板
    添加到
    映射
    ,该映射处理来自“
    的消息”
  • 将消息传递给新创建的
    ChatPanel
  • 所以我这么做了,我把代码贴在下面希望您能使用它

    如果您想对此进行测试,请首先启动
    TestChatServer
    (下面的代码),然后启动
    ChatSupervisor

    这是客户端的代码
    公共类ChatSupervisor扩展JFrame实现可运行{
    JTabbedPane tabs=新的JTabbedPane();
    Map chats=新的ConcurrentHashMap();
    公共事务监督人(){
    超级(“测试聊天”);
    添加(选项卡、边框布局、中心);
    新线程(this.start();
    }
    公开募捐{
    套接字sock=null;
    试一试{
    sock=新套接字(“localhost”,32134);
    Scanner s=新的扫描仪(sock.getInputStream());
    while(true){
    字符串from=s.next();
    字符串类型=s.next();
    字符串消息=s.nextLine();
    getChat(from).incomingMessage(类型,message);
    }
    }捕获(例外e){
    e、 printStackTrace();
    }最后{
    如果(sock!=null),请尝试{sock.close();}catch(IOException e){}
    }
    }
    公共聊天面板getChat(来自的字符串){
    如果(!chats.containsKey(from))
    chats.put(from,newchatpanel(from));
    返回聊天。获取(来自);
    }
    公共静态void main(字符串[]args){
    ChatSupervisor cs=新的ChatSupervisor();
    cs.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    cs.设置尺寸(400300);
    cs.setVisible(true);
    }
    类ChatPanel扩展了JTextArea{
    公共聊天面板(来自的最终字符串){
    SwingUtilities.invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    tabs.addTab(from,ChatPanel.this);
    }
    });
    }
    公共无效输入消息(最终字符串类型,最终字符串消息){
    SwingUtilities.invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    追加(“[”+类型+“]”+消息);
    附加(“\n”);
    }
    });
    }
    }
    }
    
    这是测试服务器的代码:
    公共类TestChatServer{
    公共静态void main(字符串[]args)引发异常{
    sockets=newserversocket(32134.accept();
    System.out.println(“已连接”);
    PrintWriter p=新的PrintWriter(s.getOutputStream());
    while(true){
    p、 println(“你好信息你好世界!”);
    p、 冲洗();
    睡眠(1000);
    对于(int i=0;i<10;i++){
    p、 println(“测试”+i+“测试”+i的警告测试”);
    p、 冲洗();
    睡眠(100);
    }
    }
    }
    }
    
    如果您发布一些相关的代码片段,可能会有所帮助。问题可能是他们没有访问同一个哈希表。使用同步方法应该没有问题,但在这种情况下不需要它们;System.out.println(System.identityHashcode(myHashtable));不,这两个类使用相同的哈希表。我从两个类threadsThanks得到了相同的Hashcode作为回复。我尝试了链接中的建议。但我仍然无法访问HashMap。两个类中的一个总是发现HashMap为空。我尝试将HashMap与Collections一起使用。synchronizedMap,问题仍然存在。如何将
    哈希表
    从一个类/线程传递到另一个类/线程?我在上面给出了应用程序源代码的快照。我已经在单独的类“DataStore”中声明了哈希表。这两个类都有对它的引用。我刚刚用我刚刚编写的聊天客户端和服务器更新了我的答案。。。希望你能使用它!
    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);
                }
            }
        }
    }