连续线程与更改对象

时间:2012-08-28 04:57:29

标签: java android multithreading asynchronous

我有以下课程:

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中,则不会发生这种情况。此外,在执行myObject时,不应执行run方法中的代码。

他们做任何非复杂的方式吗?
我只是想知道在这种情况下的最佳实践,我必须经常这样做。

3 个答案:

答案 0 :(得分:2)

首先,现在的标准做法是实现runnable而不是扩展线程(参见"implements Runnable" vs. "extends Thread")。

对于在run方法中输入的内容,while(true)是正确的想法。最终你会切换到while(someBooleanVariable),以便提供一种杀死MovementThread的方法。

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

包含所有这些修改的样本:

请注意,myObject的所有读写都在标记为synchronized的函数中。

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

答案 1 :(得分:1)

您的问题属于线程的Produce-Consumer模式。在您的情况下,Producer为1,Consumer为1

您会找到一个很好的示例,说明如何使用Concurrent BlockingQueue以上的here

使用ObjectProducer(BlockingQueue theQueue) { this.queue = theQueue; } queue.put(justProduced); Consumer(BlockingQueue theQueue) { this.queue = theQueue; } Object obj = queue.take(); 替换为双[],您就完成了。

{{1}}

答案 2 :(得分: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;
如果它没有更详细地更新您的问题,

应该有效。