2015-03-08 2 views
0

Программа зависает после попытки создать другой экземпляр самого себя, когда я жду ссылки, возвращаемой конструктором, который будет установлен.Зачем это зависание?

Если я нажму на кнопку, программа будет висеть.

Редактировать: удалить глупый второй цикл ожидания.

изменить 2: изменить true на false при вызове конструктора. программа, похоже, работает сейчас.

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.lang.reflect.InvocationTargetException; 
import javax.swing.*; 
public class Problem extends JPanel { 
    public Problem(boolean wait) { 
     frame=new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLayout(new BorderLayout()); 
     if(wait) try { 
      System.out.println("calling invoke and wait"); 
      SwingUtilities.invokeAndWait(new Runnable() { 
       public void run() { 
        Problem.this.run(); 
       } 
      }); 
     } catch(InvocationTargetException|InterruptedException e) { 
      throw new RuntimeException(e); 
     } 
     else { 
      System.out.println("calling invoke later"); 
      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        Problem.this.run(); 
       } 
      }); 
     } 
    } 
    public String title() { 
     return "title"; 
    } 
    public void addContent() { 
     JButton button=new JButton("click"); 
     add(button,BorderLayout.CENTER); 
     button.addActionListener(new ActionListener() { 
      @Override public void actionPerformed(ActionEvent arg0) { 
       Runnable runnable=new Runnable() { 
        @Override public void run() { 
         System.out.println("before new "+Thread.currentThread()); 
         problem=new Problem(false); 
         System.out.println("after new "+Thread.currentThread()); 
        } 
       }; 
       new Thread(runnable).start(); 
       System.out.println("before first wait "+Thread.currentThread()); 
       while (problem==null) 
        ; 
      } 
     }); 
    } 
    void run() { 
     frame.setTitle(title()); 
     frame.getContentPane().add(this,BorderLayout.CENTER); 
     addContent(); 
     frame.pack(); 
     frame.setVisible(true); 
    } 
    public static void main(String[] args) { 
     new Problem(false); 
    } 
    Problem problem; 
    public final JFrame frame; 
    private static final long serialVersionUID=1; 
} 

ответ

1

p1 = проблема экземпляра из основной функции

  1. Состояние 1: Создание - p1 инициализируется. p1.problem is null
  2. Состояние 2: Пользователь нажимает кнопку. В конце концов, в другом потоке создается p1.problem. Однако p1.problem.problem никогда не был инициализирован и не будет, пока пользователь не нажмет кнопку, что никогда не произойдет. Я не уверен, что вы пытаетесь сделать, но это, кажется, как ваша программа висит на while (problem.problem==null);
+0

, когда я нажимаю кнопку, программа ожидает в: Перед первой ждать –

+0

да, в то время как (problem.problem = = null) будет висеть - я отредактирую. но программа зависает при первом ожидании. –