我有以下课程:
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方法中的代码。
他们做任何非复杂的方式吗?
我只是想知道在这种情况下的最佳实践,我必须经常这样做。
答案 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
使用Object
将Producer(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;
如果它没有更详细地更新您的问题,应该有效。