这是一个启动新窗口(子窗体)的应用程序。在提交此子表单时,应该发生的是返回的数据得到处理并更新父表单。但是,启动子表单时程序不响应。有人可以解释为什么会发生这种情况,我该如何解决?
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();
}
}
答案 0 :(得分:1)
你不应该在UI线程上调用cond.await();
之类的东西(在事件调度线程上)。这就是你的UI挂起的原因。此外,即使这不相关,也不要像捕捉InterruptedException
时那样使用空的catch块。
答案 1 :(得分:1)
正如Peter所说,当等待部分从UI线程中移除并移动到BlockingMethod()时,它会起作用。此外,应该在该方法中重新获取锁,并且应该在完成处理时释放。
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();
}
}