2014-12-30 21 views
4

首先,请原谅我可怜的英语= S其次,对不起,如果我的标题有点奇怪,我不知道如何更好地制定它。同步两个不知道对方的线程[Java]

我有一点问题。我正在用Java开发一款游戏,并且按照它教给我的方式使用MVC模式。我不知道这是否是最有效的方式,但总的来说,这里是整体: 4个软件包:模型,视图,控制器和“观察者”。

在观察者中,有一个接口“Observer”,其中定义了一个元素“观察模型”应该实现的所有方法。还有一个类“Observable”,有一个观察者列表,以及所有通知他们一些变化的方法(像“fireEvent1(int i){for(Observer obs:observers)obs.Event1(i);}” ) 该模型扩展了Observable类,GUI的一些元素实现了接口Observer。

现在我的问题是:在模型的方法中,我希望模型“等待”2个用户交互。这意味着类似的东西:

  • 方法称为模型
  • 做一些东西
  • 等待用户交互的第一时间
  • 获取关于用户只是做信息(这是收集在DC型)
  • 做一些东西
  • 等待用户交互的第二次
  • 获取信息
  • 做的东西

一个精度:用户的交互被收集在其中实现的ActionListener的CONTROLER,和视图的元件具有作为CONTROLER的ActionListener。

所以我想我必须使用线程,但尽管我找到了所有的教程和例子,但我仍然无法完成这项工作。我试图在模型中启动一个线程,让它等待,但我无法实现在控制器中创建另一个线程,与第一个线程同步并在必要时通知它。我甚至不知道这是否是正确的做法,无论如何,我已经在这个问题上好几个小时了,我只是不知道如何解决这个问题。

我希望我的解释清楚,如果不是,请随时问,然后我会尝试写一个代表我的问题的简单代码。

感谢您的帮助

Scentle5S

编辑: 这里是代表我的问题一个小代码。所以我希望模型能够从视图中一个接一个地获取信息,只有两次。我在模型中启动了一个线程,并让它等待(顺便说一句,我多次看到无限循环使线程等待,但我不明白为什么它是必要的。不会简单地调用wait() ,没有循环,做这项工作呢?)。

但是很显然,这里没有其他线程与模型同步,这将能够通知何时执行动作并传输数据。

我不知道如何做这样的事情。

public class Model extends Observable { 

    public void waitForActions() { 
     System.out.println("Wating for two user's actions"); 

     Thread t = new Thread() { 
      public void run() { 
       while (true) { 
        try { 
         wait(); 
        } catch (InterruptedException e) { 
        } 
       } 
       System.out.println("First action received in model : " 
         + message); 
       while (true) { 
        try { 
         wait(); 
        } catch (InterruptedException e) { 
        } 
       } 
       System.out.println("Second action received in model : " 
         + message); 
      } 
     }; 
     fireWaitForActions(true); 
     t.start(); 
     fireWaitForActions(false); 
    } 
} 

public class Controler implements ActionListener { 
    private Model model; 

    public Controler(Model model) { 
     this.model = model; 
    } 

    public void actionPerformed(ActionEvent e) { 
     String message = ((JButton)e.getSource()).getText(); 
     System.out.println("Action received in controler : "+message); 
    } 
} 

public class View extends JFrame implements Observer { 
    private JButton b1 = new JButton("Action 1"); 
    private JButton b2 = new JButton("Action 2"); 
    private Controler controler; 

    public View(Controler controler) { 
     this.controler = controler; 

     b1.addActionListener(controler); 
     b2.addActionListener(controler); 

     b1.setEnabled(false); 
     b2.setEnabled(false); 

     JPanel container = new JPanel(); 
     container.add(b1); 
     container.add(b2); 
     setContentPane(container); 
     pack(); 
     setLocationRelativeTo(null); 
     setVisible(true); 
    } 

    public void waitForActions(Boolean b) { 
     b1.setEnabled(b); 
     b2.setEnabled(b);  
    } 
} 

public static void main(String[] args) { 
    Model model = new Model(); 
    Controler controler = new Controler(model); 
    View view = new View(controler); 
    model.addObserver(view); 
    model.waitForActions(); 
} 

这里是可观察和观测CLASSE /接口:

public class Observable { 
    private LinkedList<Observer> observers = new LinkedList<Observer>(); 

    public void addObserver(Observer obs) { 
     observers.add(obs); 
    } 

    public void fireWaitForActions(boolean b) { 
     for (Observer obs: observers) obs.waitForActions(b); 
    } 
} 

public interface Observer { 
    public void waitForActions(Boolean b); 
} 
+2

+ 1为一个非常完整和描述性的问题! (meh,不能写“+1”) – fge

+0

是的,可以用'wait'和'notify'来做到这一点。我想告诉你你做错了什么,但是你没有向我们展示任何代码。 –

+0

没有代码示例是不可能的。我甚至不能说我完全按照你的问题。如果您使用的是Swing/AWT或SWT/JFace,那么线程通常会为您生成,因此您只需实现/扩展正确的接口/类,并且如果您有超过1个线程访问相同的数据,则只需在某处添加一个'synchronized'关键字或3个。如果你把它作为一个独立的服务器应用程序来完成,没有像Spring,JEE等那么好的框架,那么你可能必须自己处理线程,并使用'synchronized'或'wait' /'notify' /'notifyAll'等被别人提及。 –

回答

0

有许多方法可以做到这一点。查看Java语言手册中的线程同步方法。

您可以在两个线程都可以看到的对象上使用wait()和notify()。 您可以使用两个线程都可以看到的Semaphore上的acquire()和release()。 您可以使用阻塞队列构建解决方案。 ()/ notify()或acquire()/ release()可能是最简单的。

0

我认为它有点混乱的解释给予你或你误会了自己的要求。每当有一个请求到达你的Web容器时,它将创建一个处理请求的线程。你是在谈论这些话题,还是你能解释一下你想要在detai中遇到什么要求?