By managing itself you might be meaning to manage synchronization on its locks and obeying the boundaries for its instance variables depending on some condition.
public class ThreadClass implements Runnable {
public void run() {
// .. Does some arbitrary work
synchronized (this) {
while (! aCondition) { // have it wait until something signals it to
// contine exection.
this.wait();
}
}
/* Reset the aCondition var to its old value to allow other threads to
enter waiting state
Continues to do more work.
Finished whatever it needed to do. Signal all other threads of this
object type to continue their work.*/
synchronized (this) {
this.notifyAll();
}
}
}
You should also take a look at the Condition interface. It seems to have the exact same requirements except that it uses the java.util.concurrent classes. There is an example of the BoundedBuffer.
See the Producer Consumer Example below. It has the same wait/notify template. The available flag is declare volatile so that thread safe reads and writes can be performed on it.
public class ProducerConsumerTest {
public static void main(String[] args) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
p1.start();
c1.start();
}
}
class CubbyHole {
private int contents;
private volatile boolean available = false;
public int get() {
synchronized (this) {
while (available == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
available = false;
synchronized (this) {
notifyAll();
}
return contents;
}
public void put(int value) {
synchronized (this) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
available = true;
contents = value;
synchronized (this) {
notifyAll();
}
}
}
class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
private Integer takeSum = new Integer(0);
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public Integer getTakeSum() {
return takeSum;
}
public void run() {
int value = 0;
for (int i = 0; i < 100; i++) {
value = cubbyhole.get();
takeSum+=value;
}
System.out.println("Take Sum for Consumer: " + number + " is "
+ takeSum);
}
}
class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
private Integer putSum = new Integer(0);
public Integer getPutSum() {
return putSum;
}
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 100; i++) {
int rnd = (int) (Math.random() * 10);
cubbyhole.put(rnd);
putSum+=rnd;
try {
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
System.out.println("Put Sum for Producer: " + number + " is " + putSum);
}
}