I would like to revise the fundamentals of Java threads on before-Java 5, so that I can understand improvements in Java 5 and beyond.
I started off with a custom collection and need help on:
- Things I am doing wrong / grossly overlooking
- How to make it better
- Suggest alternate implementation, if any
- Which is the correct place to have the
kill
variable? Is it inside the thread or in the collection like I did?
public class ThreadCreation {
public static void main(String[] args) {
MyCollection coll = new MyCollection();
coll.kill = false;
RemoveCollClass t2 = new RemoveCollClass();
t2.setName("Thread2");
t2.coll = coll;
t2.start();
AddCollClass t1 = new AddCollClass();
t1.setName("Thread1");
t1.coll = coll;
t1.start();
RemoveCollClass t3 = new RemoveCollClass();
t3.setName("Thread3");
t3.coll = coll;
t3.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
coll.kill = true;
}
static class AddCollClass extends Thread {
volatile MyCollection coll;
int count = 0;
@Override
public void run() {
while (!coll.kill) {
System.out.println(Thread.currentThread().getName()
+ " --> AddCollClass Attempt -->" + count);
coll.add();
count++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
static class RemoveCollClass extends Thread {
volatile MyCollection coll;
int count = 0;
@Override
public void run() {
// System.out.println("ThreadClass is running ");
while (!coll.kill) {
System.out.println(Thread.currentThread().getName()
+ " -->RemoveCollClass Attempt -->" + count);
coll.remove();
count++;
}
}
}
static class MyCollection {
Stack<String> container = new Stack<String>();
int maxSize = 5;
volatile boolean kill = false;
public synchronized boolean isFull() {
if (container.size() >= maxSize)
return true;
else
return false;
}
public synchronized boolean isEmpty() {
if (container.size() <= 0)
return true;
else
return false;
}
public synchronized void add() {
if (isFull()) {
try {
System.out.println("wait triggered on-->"
+ Thread.currentThread().getName());
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
notify();
}
}
if (!isFull()) {
container.add(Thread.currentThread().getName());
System.out.println(" Add Completed by "
+ Thread.currentThread().getName());
notify();
}
}
public synchronized void remove() {
if (isEmpty()) {
try {
System.out.println("wait triggered on-->"
+ Thread.currentThread().getName());
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
notify();
}
}
if (!isEmpty()) {
container.pop();
System.out.println(" Remove Completed by "
+ Thread.currentThread().getName());
}
}
}
}