3

我有以下课程:

public class MovementThread extends Thread {

    private float[] myObject;

    @Override
    public void run() {

    }

    public void setMyObject(float[] array) {
        myObject = array;
    }
}

问题是MovementThread应该一直在运行,所以我考虑while(true)Run method. 但是,myObject将从另一个更新Thread,因此如果Thread卡在Run method. 此外,run 方法中的代码在执行时也不应该myObject被执行。

他们有什么不复杂的方法吗?
我只是想知道在这种情况下的最佳实践,我认为这必须经常发生。

4

3 回答 3

2

首先,现在的标准做法是实现可运行而不是扩展线程(请参阅“实现可运行”与“扩展线程”)。

Awhile(true)是在 run 方法中放入什么的正确想法。最终,您将切换到 awhile(someBooleanVariable)以便提供一种杀死您的 MovementThread 的方法。

当前确保来自 MovementThread 运行的线程与来自其他线程的其他成员调用不冲突的当前方法是使用同步。对于简单的使用,您通常可以在函数声明前加上 synchronized,所有这些函数都不会交织在一起。

您的样品进行了所有这些修改:

请注意,myObject 的所有读取和写入都在标记为同步的函数中。

public class MovementThread extends Runnable{

    private float[] myObject;
    volatile boolean stillAlive = true;

    @Override
    public void run() {
       while (stillAlive)
       {
          processMyObject();
          Thread.sleep(1000);
       }

    }

    private synchronized void processMyObject()
    {
       // Modify or read myObject
    }

    public void kill()
    {
       stillAlive = false;
    }  

    public synchronized void setMyObject(float[] array) {
        myObject = array;
    }
}
于 2012-08-28T05:18:02.173 回答
1

您的问题属于线程的生产消费者模式。在您的情况下,生产者是1,消费者是1

你会在这里找到一个很好的例子来说明如何使用Concurrent包来做到这一点

BlockingQueue替换Object与您的 double[] 一起使用,您就完成了。

Producer(BlockingQueue theQueue) { this.queue = theQueue; }
queue.put(justProduced);
Consumer(BlockingQueue theQueue) { this.queue = theQueue; }
Object obj = queue.take();
于 2012-08-28T05:26:52.067 回答
0

由于您有两个不同的线程来修改和使用同一个对象,因此最好在您的程序中引入同步。您应该在同步块内编写代码。

现在,如果您想几乎立即为其他线程更新变量。您可以将此变量保持为 volatile。在这种情况下,一旦修改器线程更改了 myObject 值,它就会在执行器线程内更改。见伪代码:-

//Modifier thread 

synchronized(myObject){
        // do something and update the myObject
        myObject.setSomething(someValue);
}

//Executor thread

synchronized(myObject){
        //do something 
        if(myObject.getSomeValue()==someMeaningfulValue){
             myObject.execute() 
        }
}

   // To immediately update myObject, you can declare it as 

    private volatile MyObjectClassName myObject;

如果它没有用更多细节更新您的问题,那应该可以。

于 2012-08-28T05:24:59.243 回答