I might have asked earlier here, and there is lack of understanding and complex, Now I rewrite the program in a much easier way to understand.
The Problem:
When I run the 2 threads, only 1 thread do the job.
Suspicion Helper
I suspect that the thread lock itself, so that another thread cannot access it.
Code
Initialization Main
Shop shop = new Shop();
CarGenerator carGenerator = new CarGenerator(shop);
Mechanics mechanics1 = new Mechanics(shop, "Mechanics 1");
Mechanics mechanics2 = new Mechanics(shop, "Mechanics 2");
//Threads
Thread CarThread = new Thread(carGenerator);
Thread Mechanics1Thread = new Thread(mechanics1);
Thread Mechanics2Thread = new Thread(mechanics2);
CarThread.start();
Mechanics1Thread.start();
Mechanics2Thread.start();
Here we can see 2 threads are creates and work as expected.
Now what does the mechanic's function do:
@Override
public void run() {
while (true) {
System.out.println("Working Thread: " + Thread.currentThread().getName());
shop.CarFix(MechanicsName);
}
}
Clue:
Here I print out how many threads are there and the result is 2:
Working Thread: Thread-1
Working Thread: Thread-2
Great now both thread running as expected, and now I will work at the shop for infinite. I will not cut to show whole process and understand better:
public void CarFix(String MechanicsName) {
Car car;
synchronized (ListCarEntry) {
while (ListCarEntry.size() == 0) {
try {
ListCarEntry.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(Shop.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Working Thread: " + Thread.currentThread().getName());
//Done 2 Sec Fixing
//Release Now
car = (Car) ((LinkedList<?>) ListCarEntry).poll();
((LinkedList<Car>) ListCarFix).offer(car);
System.out.println("Car FIX: " + car.getCarName() + " being fixed by " + MechanicsName);
}
Here the Thread only one that is running instead of earlier 2 threads, and the result is:
Working Thread: Thread-1
Car FIX: Car 1 being fixed by Mechanics 1
Working Thread: Thread-1
Car FIX: Car 2 being fixed by Mechanics 1
Working Thread: Thread-1
Car FIX: Car 3 being fixed by Mechanics 1
Right now only Mechanics 1 fixing, while Mechanics 2 missing.
Clue 2:
When I try to REMOVE THE SLEEP FOR 2 SEC, the result is what I really want like this:
Working Thread: Thread-1
Car FIX: Car 1 being fixed by Mechanics 1
Working Thread: Thread-2
Car FIX: Car 2 being fixed by Mechanics 2
Working Thread: Thread-1
Car FIX: Car 3 being fixed by Mechanics 1
Which is what I really wanted to see.
The Question:
How to make sure thread working as expected with sleep functionality for it?
For the one who reads till the end:
See I have no idea remove sleep might solve the problem, quiet weird.. Anyway any idea guys.. and sorry for the long problem.
EDIT
This is my CarGenerator Class:
public class CarGenerator implements Runnable{
Shop shop;
public CarGenerator(Shop shop) {
this.shop = shop;
}
@Override
public void run() {
int i = 0;
while (true) {
i++;
Car car = new Car(shop, "Car " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(CarGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
Thread thCar = new Thread(car);
thCar.start();
}
}
}
Which call this car class to move the car into the shop:
public class Car implements Runnable{
private String CarName;
private Shop shop;
public Car(Shop shop, String CarName) {
this.shop = shop;
this.CarName = CarName;
}
public String getCarName() {
return CarName;
}
@Override
public void run() {
//DO
synchronized(this) {
shop.CarEntrance(this);
}
}
}
This is where the car comes into the shop
public void CarEntrance(Car car) {
System.out.println("Entry: " + car.getCarName());
if (ListCarEntry.size() == 10){
System.out.println("Exit: " + car.getCarName() + "Exit the store, cause FULL");
return;
}
((LinkedList<Car>) ListCarEntry).offer(car);
if (ListCarEntry.size() == 1) {
synchronized(ListCarEntry) {
ListCarEntry.notify();
}
}
}
As seen here I call notify Synchronized notify that being called by the mechanics wait earlier to wait for car entrance.
It's a very weird setup to begin with. Your mechanics are the threads being synchronized, but the synchronization is done in the Shop; you'd usually synchronize in the threads themselves. What's more, you don't really need explicit synchronization if you use a thread-safe queue object to manage the cars to be fixed. That makes it a typical producer/consumer problem, with the shop being the producer and the mechanics being the consumers.
This way, the mechanics will be waiting on the queue for the next car to appear.
For the solution, I just moved the Thread.sleep from the CarFix Function:
And moved it into Mechanics Class:
And the result:
And I thought the car is working 2 by 2 car, which I not really want, I want an independent Mechanics, So I tried to set the Cargenerator to 10 second for debugging test, and the result:
Now It is much fair, and works much better than expected.
Thanks for all of the contribution, and case closed.