【问题标题】:Program unresponsive on launching sub-form程序在启动子表单时无响应
【发布时间】:2014-02-01 22:53:57
【问题描述】:

这是一个启动新窗口(子表单)的应用程序。在提交此子表单时,应该会处理返回的数据并更新父表单。但是,启动子表单时程序没有响应。有人可以解释为什么会发生这种情况以及我应该如何解决它?

public class FormCondition 
{
    private JLabel nameLabel;
    private JTextField name;
    private JButton create;
    private Lock lock;
    private Condition cond;
    private String str;
    public FormCondition()
    {   
        lock = new ReentrantLock();
        cond = lock.newCondition();
        create = new JButton("Create");
        nameLabel = new JLabel("Name");
        name = new JTextField();
        name.setEditable(false);
        create.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                if (e.getSource() == create)
                {   
                    try
                    {
                        lock.lock();
                        try
                        {
                            Runnable r = new Runnable()
                            {
                                @Override
                                public void run() 
                                {
                                    System.out.println("Starting a new Thread");
                                    new newForm();
                                }
                            };

                            new Thread(r).start();
                            System.out.println("about to wait");
                            cond.await();
                            name.setText(str);
                        }
                        finally
                        {
                            lock.unlock();
                        }
                    }
                    catch (InterruptedException e1)
                    {
                        // empty
                    }
                }
            }
        });
        JFrame frame = new JFrame("Main form");
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(0, 2));
        panel.add(nameLabel);
        panel.add(name);
        panel.add(create);
        frame.add(panel);
        frame.setLocationRelativeTo(null);
        frame.setSize(200, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
    }

    public void setName(String name)
    {
        str = name;
        System.out.println("Name received is: " + str);
    }

    class newForm implements ActionListener
    {
        private JLabel nameLabel;
        private JTextField name;
        private JButton go;
        public newForm()
        {
            nameLabel = new JLabel("Name");
            name = new JTextField();
            go = new JButton("Go");
            JFrame frame=new JFrame("Second form");
            JPanel panel=new JPanel();
            panel.setLayout(new GridLayout(0,2));
            panel.add(nameLabel);
            panel.add(name);
            panel.add(go);
            frame.add(panel);
            frame.setLocationRelativeTo(null);
            frame.setSize(200,200);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        public void actionPerformed(ActionEvent e) 
        {
            if (e.getSource() == go)
            {
                lock.lock();
                try
                {
                    String string = name.getText();
                    System.out.println("Name entered is: " + str);
                    setName(str);
                    cond.signal();
                    System.out.println("Signalled");
                }
                finally
                {
                    lock.unlock();
                }

            }
        }
    }

    public static void main(String[] str)
    {
        new FormCondition();    
    }
}

【问题讨论】:

标签: java swing concurrency


【解决方案1】:

您不应该在 UI 线程(在事件调度线程上)调用 cond.await(); 之类的东西。这就是您的 UI 挂起的原因。此外,即使这不相关,也不要像在捕获 InterruptedException 时那样使用空的 catch 块。

【讨论】:

    【解决方案2】:

    当等待部分从 UI 线程中移除并移至 BlockingMethod() 时,Peter 回答它可以工作。此外,应该在该方法中重新获取锁,并在完成处理后释放锁。

     public class FormCondition 
        {
            private JLabel nameLabel;
            private JTextField name;
            private JButton create;
            private ReentrantLock lock;
            private Condition cond;
            private String str;
            public FormCondition()
        {   
            lock=new ReentrantLock();
            cond=lock.newCondition();
            create=new JButton("Create");
            nameLabel=new JLabel("Name");
            name=new JTextField();
            name.setEditable(false);
            create.addActionListener(new ActionListener(){
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    if(e.getSource()==create)
                    {   
                        try
                        {
                            lock.lock();
                            System.out.println("Lock acquired");
                            System.out.println("Starting a new Thread");
                            System.out.println("Sleep for two minutes");
                            Thread.sleep(2000);
                            System.out.println("Awake now");
                            new newForm();
                            lock.unlock();
                            blockingMethod();
    
    
    
    
                        }
                        catch(InterruptedException e1)
                        {
                        e1.getMessage() ;
    
                        }
    
    
                    }
    
                }});
            JFrame frame=new JFrame("Main form");
            JPanel panel=new JPanel();
            panel.setLayout(new GridLayout(0,2));
            panel.add(nameLabel);
            panel.add(name);
            panel.add(create);
            frame.add(panel);
            frame.setLocationRelativeTo(null);
            frame.setSize(400,200);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
        }
    
    
    
        public void blockingMethod()
        {
            Runnable r2=new Runnable(){
    
                @Override
                public void run() 
                {
    
                    try 
                    {   lock.lock(); 
                        System.out.println("about to wait");
                        cond.await();//lock released temporarily
                        System.out.println("waiting done...");
                        //invoke setName after reaquiring lock
                        lock.unlock();
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
    
    
                }};
                try
                {
                        lock.lock();
                        System.out.println("Still has the Lock ");
                        new Thread(r2).start();
                        lock.unlock();
    
    
                }
                catch(Exception e1)
                {
                e1.getMessage() ;
    
                }
    
        }
    
        public void setName(String name)
        {
    
        str=name;
        this.name.setText(str);
        System.out.println("Name received is: "+str);
        }
    
        class newForm  implements ActionListener
        {
        private JLabel nameLabel;
        private JTextField name;
        private JButton go;
        public newForm()
        {
        nameLabel=new JLabel("Name");
        name=new JTextField();
        go=new JButton("Go");
        go.addActionListener(this);
        JFrame frame=new JFrame("Second form");
        JPanel panel=new JPanel();
        panel.setLayout(new GridLayout(0,2));
        panel.add(nameLabel);
        panel.add(name);
        panel.add(go);
        frame.add(panel);
        frame.setLocationRelativeTo(null);
        frame.setSize(300,200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    
        }
        public void actionPerformed(ActionEvent e) 
        {
    
            if(e.getSource()==go)
            {
                System.out.println("waiting for the lock");
                 lock.lock();
                 System.out.println("Lock acquired");
    
                     try
                     {
    
                      String string= name.getText();
                      System.out.println("Name entered is: "+string);
                      setName(string);
                      cond.signalAll();
                      System.out.println("Signalled");
                     }
    
                     finally
                     {
                         lock.unlock();
                         System.out.println("Lock released");
    
                     }
    
    
    
    
            }
    
        }
        }
    
        public static void main(String[] str)
        {
        new FormCondition();    
        }
        }
    

    【讨论】:

      猜你喜欢
      • 2018-03-24
      • 1970-01-01
      • 2012-11-19
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      • 2018-07-06
      • 2016-08-05
      相关资源
      最近更新 更多