3

I have the following class:

public class MovementThread extends Thread {

    private float[] myObject;

    @Override
    public void run() {

    }

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

The thing is that MovementThread should be running all the time, so I thought about putting a while(true) in the Run method. However, myObject will be updated from another Thread, so it won't happen if the Thread is stuck in the Run method. Also the code in the run method should not be executed when myObject is being executed.

Is their any non complicated way of doing this ?
I'm just wondering about best practice in this case, which must happen pretty often I reckon.

chopchop
  • 1,905
  • 2
  • 22
  • 37
  • `MovementThread` doesn't have to be free to be updated on the value of `myObject`. Just ensure you mark the field `volatile` to ensure write visibility for all threads. – obataku Aug 28 '12 at 05:07

3 Answers3

2

First things first, standard practice nowadays is to implement runnable rather than extending thread(see "implements Runnable" vs. "extends Thread").

A while(true) is the correct idea for what to put in the run method. Eventually you would switch over to a while(someBooleanVariable) so as to provide a way of killing your MovementThread.

The current way to make sure that the thread from MovementThread's run does not conflict with other member calls from other threads is to use synchronized. For simple uses, you can usually prefix the function declaration with synchronized and all such functions will not interweave.

Your sample with all of these modifications:

Note that all reads and writes of myObject are in functions marked 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;
    }
}
Community
  • 1
  • 1
  • I think *Synchronized blocks* should be used since they lock object for a shorter period. see http://stackoverflow.com/questions/574240/synchronized-block-vs-synchronized-method – Amit Aug 28 '12 at 05:28
  • @veer I thought synchronized already dealt with the memory issues. Looking for docs now. –  Aug 28 '12 at 05:33
  • so why is stillAlive volatile? – chopchop Aug 28 '12 at 06:04
  • @chopchop The methods where stillAlive is accessed, kill and run are not synchronized. Therefore stillAlive has to be explicitly "protected" from the compiler with volatile. Volatile is very limited and only helps with simple isolated get or set operations. Anything fancier like increments(which is a combined get+set) or sequences of actions with the same object(like `if (blah == 3) blah = 2;`) will not be helped by volatile. –  Aug 29 '12 at 02:00
1

Your problem falls in Produce-Consumer pattern for threads. In your case Producer is 1 and Consumer is 1.

You will find a good example of how to do it using Concurrent package over here

Use BlockingQueue Replace Object with your double[] and you are done.

Producer(BlockingQueue theQueue) { this.queue = theQueue; }
queue.put(justProduced);
Consumer(BlockingQueue theQueue) { this.queue = theQueue; }
Object obj = queue.take();
Amit Deshpande
  • 19,001
  • 4
  • 46
  • 72
0

Since you have two different threads to modify and use the same object the best will be to introduce the synchronization in your program. You should write the code inside the synchronization blocks.

Now, If you want to update the variable almost immediately for other thread. You can keep this variable as volatile. In that case myObject value will be changed inside the executor thread as soon as it is changed my the modifier thread. See pseudo code:-

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

that should work, if it doesn't update your question with more details.

Amit
  • 13,134
  • 17
  • 77
  • 148