I haven't fully grasped all of what I've read about synchronized
access to data from threads, and haven't seen examples doing exactly
what I want to do. Can you tell me if this will work.
I want to have 2 threads, with one thread doing non-blocking I/O, and
the other doing other things. When the later thread is done, it needs
to signal to the thread doing I/O, to wrap it up and quit.
Would something like this be a problem:
class A {
private boolean done = false;
class B extends Thread {
private A caller;
public B(A c) { caller = c; }
public void run() {
while (true) {
// do stuff
if (caller.isDone()) {
// wrap it up
return;
}
}
}
}
public static void main(String[] args) {
B b = new B();
b.start();
// do stuff
done = true;
b.join();
}
// I think synchronized guarentees that the instance of B
// doesn't use a local copy of the boolean value
public synchronized boolean isDone() { return done; }
}
Frank Fredstone - 04 Aug 2006 20:26 GMT
Oops:
> public static void main(String[] args) {
> B b = new B();
[quoted text clipped - 3 lines]
> b.join();
> }
A a = new A();
a.makeItGo();
...
public void makeItGo() {
B b = new B(this);
b.start();
// do stuff
done = true;
b.join();
}
> // I think synchronized guarentees that the instance of B
> // doesn't use a local copy of the boolean value
> public synchronized boolean isDone() { return done; }
> }
Frank Fredstone - 04 Aug 2006 20:40 GMT
Or, the following works.., but can it cause a problem?
import java.util.concurrent.atomic.AtomicBoolean;
public class Test {
private AtomicBoolean done = new AtomicBoolean(false);
class TestThread extends Thread {
private String name;
private AtomicBoolean done;
public TestThread(final String n, final AtomicBoolean d) {
name = n;
done = d;
}
public void run() {
while (true) {
System.out.println(name);
try {
Thread.currentThread().sleep(100);
} catch (Exception ex) {
System.out.println("" + ex);
return;
}
if (done.get()) {
return;
}
}
}
}
public static void main(String[] args) throws Exception {
Test t = new Test();
t.run();
}
public void run() {
TestThread ta = new TestThread("a", done);
TestThread tb = new TestThread("b", done);
ta.start();
tb.start();
for (int i = 0; i < 10; ++i) {
System.out.println("main: " + i);
try {
Thread.currentThread().sleep(100);
} catch (Exception ex) {
System.out.println("" + ex);
break;
}
}
done.set(true);
try {
ta.join();
tb.join();
} catch (Exception ex) {
System.out.println("" + ex);
}
}
}
hiwa - 05 Aug 2006 06:44 GMT
If you have only two threads running, class/app global state being only
modified by one and only once and there's no requirement for
conditional wait, your first example should suffice. No synchronization
would be needed, I believe because there are no race conditions around
the state access.