I have a method and a thread which I'd like to run in the following order: First the method should d开发者_开发技巧o something with an object, and then the thread should do something with the object. They share the same object. I have to synchronize them, but I am just meeting with Threads. How can I do that?
private synchronized method()
{
//do something with an object (a field)
}
Runnable ObjectUpdater = new Runnable()
{
//do something with the object after the method has finished
}
My code, that somehow manages to freeze my Main thread (where the method is) My thread code:
private Runnable something = new Runnable(){
synchronized (this){
while (flag == false)
{ try {wait();)
catch (IntExc ie) {e.printStackTrace...}
}
//here it does its thing
}
setFlag(false);
}
My method code (part of the main thread)
private void Method()
{
//do its thing
setFlag(true);
notifyAll();
}
To me that is simple questions
" you said that I do not know which is going to access the object first - the separate ObjectUpdater thread, or the main thread (with the method). If the separate thread accesses it before the main thread, that is bad and I don't want this to happen"
if you want the main thread method to call first then the objectUpdater thread , have a flag to know whether the method is visited first by main thread ,if it is updater then call wait to this thread , once main finishes it call notify which will run separator thread, to know which thread is main thread or updater thread , set a name to the thread while creating it. and get the name as Thread.currentThread().getName().
Use the Semaphore class to allow access to the object.
public class Main
{
public static void main (String[] args) {
final Obj obj = new Obj();
final Semaphore semaphore = new Semaphore(0);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
return;
}
obj.doSomething();
}
});
t.setName("test");
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
obj.doSomething();
semaphore.release();
}
}
class Obj {
public void doSomething() {
System.out.println("something done by " + Thread.currentThread());
}
}
Apart from synchronizing on the object, you could call the method as first statement in the new thread, or you could start the new thread at the end of the method.
It is hard to say what is the best approach in your case, maybe you can give us some more details on the how and what?
Update
In answer to your code (for some reason I cannot add another comment...)
Is the method called from a synchronized(this)
block? If not the notifyAll()
should be in a synchronized block. Also, can you update the code to show where/how your main thread interacts with the method and the object?
I think better approach would be to call the method using which you want to perform something with an object, and then declare the thread which would do something with an object.
精彩评论