Running multiple threads in Java
My task is to imitate the activity of a couple of people. Each of them has several actions to perform at any time: fast (0-5 seconds), medium (5-10 seconds), slow (10-20 seconds), and very slow (20-30 seconds). Each person performs their task independently at the same time. At the start of a new task, I have to print this random time, start the task, and then after the time passes, show the next task and start it. I wrote a run () function that takes time into account, but now it looks like the threads are running one after the other and not at the same time, or maybe they just print this way.
public class People{
public static void main(String[] args){
Task tasksA[]={new Task("washing","fast"),
new Task("reading","slow"),
new Task("shopping","medium")};
Task tasksM[]={new Task("sleeping zzzzzzzzzz","very slow"),
new Task("learning","slow"),
new Task(" :** ","slow"),
new Task("passing an exam","slow") };
Task tasksJ[]={new Task("listening music","medium"),
new Task("doing nothing","slow"),
new Task("walking","medium") };
BusyPerson friends[]={ new BusyPerson("Alice",tasksA),
new BusyPerson("Mark",tasksM),
new BusyPerson("John",tasksJ)};
System.out.println("STARTING.....................");
for(BusyPerson f: friends)
(new Thread(f)).start();
System.out.println("DONE.........................");
}
}
class Task {
private String task;
private int time;
private Task[]tasks;
public Task(String t, String s){
task = t;
Speed speed = new Speed();
time = speed.getSpeed(s);
}
public Task(Task[]tab){
Task[]table=new Task[tab.length];
for(int i=0; i < tab.length; i++){
table[i] = tab[i];
}
this.tasks = table;
}
}
class Speed {
private static String[]hows = {"fast","medium","slow","very slow"};
private static int[]maxs = {5000, 10000, 20000, 30000};
public Speed(){
}
public static int getSpeed( String speedString){
String s = speedString;
int up_limit=0;
int down_limit=0;
int time=0;
//get limits of time
for(int i=0; i<hows.length; i++){
if(s.equals(hows[i])){
up_limit = maxs[i];
if(i>0){
down_limit = maxs[i-1];
}
else{
down_limit = 0;
}
}
}
//get random time within the limits
Random rand = new Random();
time = rand.nextInt(up_limit) + down_limit;
return time;
}
}
class BusyPerson implements Runnable {
private String name;
private Task[] person_tasks;
private BusyPerson[]persons;
public BusyPerson(String s, Task[]t){
name = s;
person_tasks = t;
}
public BusyPerson(BusyPerson[]tab){
BusyPerson[]table=new BusyPerson[tab.length];
for(int i=0; i < tab.length; i++){
table[i] = tab[i];
}
this.persons = table;
}
public void run() {
int time = 0;
double t1=0;
for(Task t: person_tasks){
t1 = (double)t.time/1000;
System.out.println(name+" is... "+t.task+" "+t.speed+
" ("+t1+" sec)");
while (time == t.time) {
try {
Thread.sleep(10);
} catch(InterruptedException exc) {
System.out.println("End of thread.");
return;
}
time = time + 100;
}
}
}
}
And my conclusion:
STARTING.....................
DONE.........................
Mark is... sleeping zzzzzzzzzz very slow (36.715 sec)
Mark is... learning slow (10.117 sec)
Mark is... :** slow (29.543 sec)
Mark is... passing an exam slow (23.429 sec)
Alice is... washing fast (1.209 sec)
Alice is... reading slow (23.21 sec)
Alice is... shopping medium (11.237 sec)
John is... listening music medium (8.263 sec)
John is... doing nothing slow (13.576 sec)
John is... walking medium (11.322 sec)
For now, it should be like this:
STARTING.....................
DONE.........................
John is... listening music medium (7.05 sec)
Alice is... washing fast (3.268 sec)
Mark is... sleeping zzzzzzzzzz very slow (23.71 sec)
Alice is... reading slow (15.516 sec)
John is... doing nothing slow (13.692 sec)
Alice is... shopping medium (8.371 sec)
Mark is... learning slow (13.904 sec)
John is... walking medium (5.172 sec)
Mark is... :** slow (12.322 sec)
Mark is... passing an exam very slow (27.1 sec)
source to share
It seems that your wait loop has a wrong termination condition using time == t.time
instead time <= t.time
. Also, it seems to be increasing by 100 instead of 10 on each iteration.
Also, you must reset before each cycle time
.
In other words, the cycle
while (time == t.time) {
try {
Thread.sleep(10);
} catch(InterruptedException exc) {
System.out.println("End of thread.");
return;
}
time = time + 100;
}
it should be
time = 0;
while (time <= t.time) {
try {
Thread.sleep(10);
} catch(InterruptedException exc) {
System.out.println("End of thread.");
return;
}
time += 10;
}
or use a for loop instead:
for (int time = 0; time <= t.time; time += 10) {
try {
Thread.sleep(10);
} catch(InterruptedException exc) {
System.out.println("End of thread.");
return;
}
}
However, there really is no reason to sleep in 10 millisecond increments. It Thread.sleep()
may also be inaccurate. Better to try the entire period at one time and check the clock.
long timeToWakeup = System.currentTimeMillis() + t.time;
long sleepMs = t.time;
while (sleepMs > 0) {
try {
Thread.sleep(sleepMs);
} catch(InterruptedException exc) {
System.out.println("End of thread.");
return;
}
sleepMs = timeToWakeup - System.currentTimeMillis());
}
source to share