同步两个彼此不认识的线程[Java]

时间:2021-03-19 19:40:18

First of all, excuse my poor english =S Second, sorry if my title is a little weird, I didn't know how to formulate it better.

首先,请原谅我可怜的英语= S第二,抱歉,如果我的标题有点奇怪,我不知道如何更好地表达它。

I have a little problem. I'm developing a game in Java and I'm using the MVC pattern the way it has been taught to me. I don't know if this is the most efficient way but anyway, here is the overall thing : 4 packages : model, view, controler, and "observer".

我有一点问题。我正在开发一个Java游戏,我正在按照它教给我的方式使用MVC模式。我不知道这是否是最有效的方式,但无论如何,这是整体的事情:4个包:模型,视图,控制器和“观察者”。

In observer, there is one interface "Observer", in which are defined all the methods that an element "observing the model" should implement. There is also a class "Observable", with a list of observers, and all the methods notifying them of some changes (methods like "fireEvent1(int i) { for (Observer obs: observers) obs.Event1(i); }") The model extends the class Observable and some elements of the GUI implements the interface Observer.

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

Now my problem is : In a method in the model, I want the model to "wait" for 2 user interactions. That means something like that :

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

  • method called in the model
  • 模型中调用的方法

  • do some stuff
  • 做一些事情

  • wait for the user to interact the 1st time
  • 等待用户第一次进行交互

  • get informations about what the user just did (which are collected in the controler)
  • 获取有关用户刚刚做了什么的信息(在控制器中收集的信息)

  • do some stuff
  • 做一些事情

  • wait for the user to interact the 2nd time
  • 等待用户第二次进行交互

  • get informations
  • do stuff
  • end

One precision : the interactions of the user are collected in the controler which implements ActionListener, and the elements of the view have the controler as ActionListener.

一个精度:用户的交互在实现ActionListener的控制器中收集,视图的元素将控制器作为ActionListener。

So I suppose I have to use threads, but despite all the tutorials and exemples I have found, I'm still not able to make this work. I tried to start a thread in the model, make it wait, but I just can't achieve making another thread in the controler, synchronized with the first one and notify it when necessary. I don't even know if this is the right thing to do, anyway, I've been on this problem for hours and I just don't know how to solve it.

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

I hope my explanations were clear, if not, please feel free to ask, I will then try to write a simple code representing my problem.

我希望我的解释清楚,如果没有,请随意问,我会尝试写一个代表我的问题的简单代码。

Thanks for your help

谢谢你的帮助

Scentle5S

EDIT: Here is a small code representing my problem. So I would like the model to be able to get the informations from the view, one after the another, only two times. I start a thread in the model and make it wait (by the way, I saw many times that infinite loop to make the thread wait, but I don't understand why it is necessary. Wouldn't a simple call to wait(), with no loop, do the job as well ?).

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

But it is obvious that there is no other thread here synchronized with the model, which would be able able to notify when the action is performed and transmit the data.

但显而易见的是,此处没有其他线程与模型同步,该模型能够在执行操作时通知并传输数据。

I have no idea how to do such a thing.

我不知道怎么做这样的事情。

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();
}

Here are the Observable and Observer classe/interface :

这是Observable和Observer 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);
}

3 个解决方案

#1


0  

There are a number of ways to do this. Look in your Java language manual for thread synchronization methods.

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

You can use wait() and notify() on an Object that both threads can see. You can use acquire() and release() on a Semaphore that both threads can see. You can probably build a solution using Blocking Queues.

您可以对两个线程都可以看到的Object使用wait()和notify()。您可以在两个线程都可以看到的信号量上使用acquire()和release()。您可以使用阻塞队列构建解决方案。

wait()/notify() or acquire()/release() are probably easiest.

wait()/ notify()或acquire()/ release()可能是最简单的。

#2


0  

To synchronize two (or more threads) not being able to know each other you need an object common to both of the Threads. You can easily use a lock from the

要同步两个(或多个线程)无法相互了解,您需要两个线程共有的对象。你可以轻松地使用锁

java.util.concurrent.locks

package.

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/package-summary.html

For example create a ReentranceLock and simply use

例如,创建一个ReentranceLock并简单地使用

.lock()

and

.unlock()

#3


0  

I think its a little confusing explanation given by you or you misunderstood your own requirement. Whenever there is a request coming to your web container its will create a thread for handling thi srequest. Are you talking about those threads or can you explain what is the requirement yu want to met in detai.

我认为你或你误解了自己的要求会引起一些令人困惑的解释。每当有一个请求进入您的Web容器时,它将创建一个处理该srequest的线程。您是在谈论这些线索还是可以解释您希望在详细信息中遇到的要求。

#1


0  

There are a number of ways to do this. Look in your Java language manual for thread synchronization methods.

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

You can use wait() and notify() on an Object that both threads can see. You can use acquire() and release() on a Semaphore that both threads can see. You can probably build a solution using Blocking Queues.

您可以对两个线程都可以看到的Object使用wait()和notify()。您可以在两个线程都可以看到的信号量上使用acquire()和release()。您可以使用阻塞队列构建解决方案。

wait()/notify() or acquire()/release() are probably easiest.

wait()/ notify()或acquire()/ release()可能是最简单的。

#2


0  

To synchronize two (or more threads) not being able to know each other you need an object common to both of the Threads. You can easily use a lock from the

要同步两个(或多个线程)无法相互了解,您需要两个线程共有的对象。你可以轻松地使用锁

java.util.concurrent.locks

package.

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/package-summary.html

For example create a ReentranceLock and simply use

例如,创建一个ReentranceLock并简单地使用

.lock()

and

.unlock()

#3


0  

I think its a little confusing explanation given by you or you misunderstood your own requirement. Whenever there is a request coming to your web container its will create a thread for handling thi srequest. Are you talking about those threads or can you explain what is the requirement yu want to met in detai.

我认为你或你误解了自己的要求会引起一些令人困惑的解释。每当有一个请求进入您的Web容器时,它将创建一个处理该srequest的线程。您是在谈论这些线索还是可以解释您希望在详细信息中遇到的要求。