I want to simulate a scheduler in java. I have three threads defined. Now I want to execute Thread 1 to be take 10% time, Thread 2 to take 30% and Thread 3 to take remaining 60% of time approximately.
All the three threads are continous monitoring tasks which will never end.
i.e. If I execute the program for 100 minutes, then Thread 1 executes for 10 mins, Thread 2 for 30 mins & Thread 3 for 60 minutes.
and also whenever threads are being shifted (i.e. another threading going into running state), I should print that "Thread x executed for Y seconds"
Can any one please provide some pointers on achieving the above simulation in java.
This link should be interresting.
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MainThread
{
public static void main(String[] args)
{
int corePoolSize = 2;
ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(corePoolSize);
/*
* This will execute the WorkerThread immediately
*/
stpe.execute(new WorkerThread("WorkerThread-Running-Immediately"));
/*
* This will execute the WorkerThread only once after 10 Seconds
*/
stpe.schedule(new WorkerThread("WorkerThread-Scheduled-After-10-seconds"), 10, TimeUnit.SECONDS);
/*
* This will execute the WorkerThread continuously for every 5 seconds with an initial delay of 10
* seconds for the first WorkerThread to start execution cycle. In this case, whether the first
* WorkerThread is completed or not, the second WorkerThread will start exactly after 5 seconds hence
* called schedule at fixed rate. This continues till 'n' threads are executed.
*/
stpe.scheduleAtFixedRate(new WorkerThread("WorkerThread-Running-At-Fixed-Rate"), 10, 5, TimeUnit.SECONDS);
/*
* This will execute the WorkerThread continuously with an initial delay of 10 seconds for the first
* WorkerThread to start execution cycle. Once the first thread execution completes then a delay of 5
* Seconds is introduced so that the next WorkerThread execution cycle starts. This continues till
* 'n' thread are executed. This is called schedule each thread with a fixed delay.
*/
stpe.scheduleWithFixedDelay(new WorkerThread("WorkerThread-Running-With-Fixed-Delay"), 10, 5, TimeUnit.SECONDS);
}
}
And a worker thread :
public class WorkerThread implements Runnable
{
private String threadName = null;
public WorkerThread(String threadName)
{
this.threadName = threadName;
}
public void run()
{
System.out.println(this.threadName + " started...");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(this.threadName + " ended...");
}
}
Related
Talk is cheap. Show the code.
MyCyclicBarrier.java
public class MyCyclicBarrier extends Thread{
private CyclicBarrier cyclicBarrier;
public MyCyclicBarrier(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
#Override
public void run() {
System.out.println("Thread start." + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(2); //biz code
System.out.println("Thread "+Thread.currentThread().getName()+" is waiting for the other Threads."+
"\n\t\t\t\tIt's parties is "+cyclicBarrier.getParties()+
"\n\t\t\t\tWaiting for "+cyclicBarrier.getNumberWaiting()+" Threads");
cyclicBarrier.await(3,TimeUnit.SECONDS);
} catch (InterruptedException | BrokenBarrierException | TimeoutException e) {
e.printStackTrace();
}
System.out.println("Thread end."+Thread.currentThread().getName());
}
}
TestCyclicbarrier.java
public class TestCyclicbarrier1 {
public static void main(String[] args) {
int length = 5;
long start = System.currentTimeMillis();
CyclicBarrier cyclicBarrierWithRunnable = new CyclicBarrier(length, () -> {
System.out.println("the final reach Thread is " + Thread.currentThread().getName());
long end = System.currentTimeMillis();
System.out.println("cost totally :" + (end - start) / 1000 + "s");
});
for (int i = 0; i < length; i++) {
if (i != 4) {
new MyCyclicBarrier(cyclicBarrierWithRunnable).start();
} else {
try {
TimeUnit.SECONDS.sleep(2);
new MyCyclicBarrier(cyclicBarrierWithRunnable).start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Output:
Thread start.Thread-1
Thread start.Thread-0
Thread start.Thread-2
Thread start.Thread-3
Thread Thread-0 is waiting for the other Threads.
It's parties is 5
Waiting for 0 Threads
Thread Thread-3 is waiting for the other Threads.
It's parties is 5
Waiting for 0 Threads
Thread start.Thread-4
Thread Thread-1 is waiting for the other Threads.
It's parties is 5
Waiting for 0 Threads
Thread Thread-2 is waiting for the other Threads.
It's parties is 5
Waiting for 1 Threads
Thread Thread-4 is waiting for the other Threads.
It's parties is 5
Waiting for 4 Threads
the final reach Thread is Thread-4
cost totally :4s
Thread end.Thread-4
Thread end.Thread-0
Thread end.Thread-3
Thread end.Thread-2
Thread end.Thread-1
I am searching for a long time on net. But no similar answer. Please help or try to give some ideas! And I just start to learn CyclicBarrier.
I wonder if I have misunderstood CyclicBarrier.await(int timeout,TimeUnit unit). Threads 0 through 3 have already reached the barrier point that cost 2s.In the same time the final Thread started after 2s of waiting.After 1 second number 0 to 3 Threads reach the specified timeout which number 4 thread still excuted its own code. Here is the question: Why did CyclicBarrier.await(int timeout, TimeUnit unit) didn't throw TimeOutException here?
Threads 0 through 3 have already reached the Barrier point that cost 2s.
This is correct.
In the same time the final Thread started after 2s of waiting.
Correct. Note, by the time this thread starts, other 4 threads are awaiting the CB (3 secs timeout i.e., we have 3 secs until a TimeoutException can occur).
But thread 4 sleeps for only 2 seconds in the run method (we still have only 1 sec until the TimeoutException).
When it comes to await, it is the last thread - so it doesn't have to wait anymore. Hence the barrier action gets run and others are unblocked - from javadoc,
If the current thread is the last thread to arrive, and a
non-null barrier action was supplied in the constructor, then the current thread runs the action before allowing the other threads to continue.
If you make sleep for four seconds before starting thread-4, you would get a TimeoutException.
try {
TimeUnit.SECONDS.sleep(4);
new MyCyclicBarrier(cyclicBarrierWithRunnable).start();
} catch (InterruptedException e) {
e.printStackTrace();
}
You seem to think that the timeout starts when the thread starts:
Threads 0 through 3 have already reached the Barrier point that cost 2s.
After 1 second number 0 to 3 Threads reach the specified timeout
This is wrong. When you call
cyclicBarrier.await(3,TimeUnit.SECONDS);
it doesn't matter how long it took the threads to reach that point - the timeout is 3 seconds from the moment the method cyclicBarrier.await() is called.
Since thread 4 has only an additional delay of 2 seconds it still arrives in time.
To clarify further this is what the timeline looks like:
t=0s
main() creates the CyclicBarrier and starts threads 0 to 3
the threads 0 to 3 start and call TimeUnit.SECONDS.sleep(2);
main calls TimeUnit.SECONDS.sleep(2);
t=2s
main() starts thread 4
the threads 0 to 3 awake, print out something and then call cyclicBarrier.await(3,TimeUnit.SECONDS); which means that they will be interrupted at t=5s (t=2s + 3s)
thread 4 stars and calls TimeUnit.SECONDS.sleep(2);
t=4s
thread 4 awakes, prints out something and then calls cyclicBarrier.await(3,TimeUnit.SECONDS);.
since now all threads are within cyclicBarrier.await(3,TimeUnit.SECONDS);, the condition for the CyclicBarrier is fulfilled and all threads continue
the timeout for thread 4 doesn't get used (because it is the last thread to reach the CyclicBarrier)
for threads 0 to 3 the timeout at t=5s is never reached
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Processor implements Runnable {
private CountDownLatch latch;
public Processor(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Started.");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}
// -----------------------------------------------------
public class App {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(5); // coundown from 5 to 0
ExecutorService executor = Executors.newFixedThreadPool(2); // 2 Threads in pool
for(int i=0; i < 10; i++) {
executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
}
try {
latch.await(); // wait until latch counted down to 0
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Completed.");
}
}
Output:
Started
Started
Started
Started
Started
Started
Started
Completed`
Started
Started
Started
In the above code "Completed" should be printed after 6 times "Started" as latch count downs to 5 - 0, why it is always 7th or 8th time? Have i understood wrong?
Your thread pool has size 2 and your Processor threads take 3 seconds to execute.
First two Processors threads are started, the both print Started and they finish 3 seconds later.
Then the next two are started and again they both print Started and finish 3 second later.
Then another two (5th and 6th) are started, print Started and 3 seconds later when one of them (or both) finishes. At this point there are multiple things that are going to happen at roughly the same time (so the order is kind of random):
The main thread resumes and prints Completed
7th Processor thread is started and prints Started
8th Processor thread is started and prints Started
Therefore, Completed is always going to be preceded by 6, 7 or 8 Started print outs.
So, CountDownLatch does not guarantee that it will resume the parent thread (here I mean the thread from which you have called latch.await();) execution as soon as the Count Down goes to 0. So, what happens when Count Down latch countdown to 0 that means now parent Thread can resume its work and that does not mean it will get the get the CPU then and there. So, it can resume that does not mean CPU schedule the parent thread as soon as the countdown to 0. If there are other threads then is there is a possibility that those can execute before the parent thread. In your case, it ensures that it will not execute before the 5 time printing Started but it does ensure that it will be exactly after printing 5 times Started. You may also observe at a certain execution of your code Completed is printing at end of all Started printing.
I have thread x which I start like so:
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(() -> {
Inside x I have a CyclicBarrier with another 10 threads:
final CyclicBarrier _threadGate = new CyclicBarrier(10);
ArrayList<Thread> _threadList = new ArrayList<>();
Then I add the thread to the list
for (int i = 0; i < 10; i++) {
_threadList.add(new Thread() {
#Override
public void run() {
_threadGate.await();
//long processing code
So after the threads are ready I start them, it is important for them to start at the same time (well almost, looping takes time, even if its 0,01ms):
for (int i = 0; i < _threadList.size(); i++) {
_threadList.get(i).start();
}
Now, the end of x, the main thread, is like this:
}, 0, repeatTimer, TimeUnit.SECONDS);
If repeatTimer is 300 this means that it starts again the 10 threads after 5 minutes.
The time for the 10 threads to finish is an UNKNOWN amount, but it is under 5 minutes. Somewhere between 2 and 4 minutes for sure.
What I want to achieve
Once the 10 threads finish, restart X but with a delay of 5 seconds.
For this I have been thinking of setting the repeatTimer value to the time elapsed by the 10 threads + 5 seconds (I dont know how to do it, I dont know w hen last thread finishes its task), but is this correct? or is there another way of doing it?
I don't see the necessity of having SchedulingExecutorService here. You can just wait until all threads finish their job using CountDownLatch.
Here's a simple exapmple:
while (!stopped) {
CountDownLatch latch = new CountDownLatch(N);
// create and start your threads
latch.await(); // this method blocks until each Thread calls countDown()
// wait here 5 seconds if you want
}
Decrement the latch in last action of each thread:
public void run() {
_threadGate.await();
// thread actions
latch.countDown();
}
I am beginner in programming and Java, and this is my first multi-core program. The problem is that my program never uses more than 13% of my CPU. I do not know if I do it in the right way or not.
How do I compute faster and use more CPU resources?
My program consists of three class:
The "main class that instantiates the Work object with a number of threads
A "T1" class that extends Thread and contains the work to be performed
A "Work" class that launches the desired thread numbers and displays the time taken by all threads to perform the work
Here is the code of my Main class:
public static void main(String[] args) {
System.out.println("Number of CPUs available = " + Runtime.getRuntime().availableProcessors()); //Display the number of CPUs available
int iteration = 100000000; // Define a number of itterations to do by all threads
/*
Instantiates each work with a different number of threads (1, 4, 8, 12, and 24)
*/
Work t1 = new Work(1);
Work t4 = new Work(4);
Work t8 = new Work(8);
Work t12 = new Work(12);
Work t24 = new Work(24);
/*
Launch the work for each thread with the specified number of iterations
*/
t1.goWork(iteration);
t4.goWork(iteration);
t8.goWork(iteration);
t12.goWork(iteration);
t24.goWork(iteration);
}
And here the Work class code:
public class Work {
static long time; // A variable that each thread increase by the time it takes to complete its task.
static int itterationPerThread; // A variable that stores the number of itterations Per Thread to do.
static int finish; // A variable that each thread incrase when it finish its task, used to wait until all thread has complete their task.
private int numberOfThreads; // The number of threads to launch.
/**
*
* The constructor, set the number Of threads to run
* #param numberOfThreads
*/
public Work(int numberOfThreads)
{
this.numberOfThreads = numberOfThreads; //Set the number of threads
}
/**
*
* A method that launch a specified number of thread in the constructor of the class, and distributes the a number of iteration of each thread.
* The method does nothing until each thread completes its task and print the time needed for all threads to complete their tasks.
* #param itterationPerThread
*/
public void goWork(int itterationPerThread)
{
finish = 0; //Reset the variable in the case that we call the method more than one time
time = 0; //Reset the variable in the case that we call the method more than one time
this.itterationPerThread = itterationPerThread/numberOfThreads; // Divide the given number of iterations by the number of threads specified in the constructor
for (int i=0; i<numberOfThreads; i++) //Launch the specified number of threads
{
new T1().run();
}
while (finish != numberOfThreads) //Do nothing until all thread as completed their task
{
}
System.out.println("Time for " + numberOfThreads + " thread = " + time + " ms"); //Display the total time
}
}
And finally my T1 class:
public class T1 extends Thread{
#Override
public void run()
{
long before = System.currentTimeMillis();
for (int i=0; i<Work.itterationPerThread; i++) //Get the thread busy with a number of itterations
{
Math.cos(2.1545); //Do something...
}
long after = System.currentTimeMillis(); //Compute the elapsed time
Work.time += after - before; //Increase the static variable in Work.java by the time elapsed for this thread
Work.finish++; // Increase the static variable in Work.java when the thread has finished its job
}
}
The programme gives me the following ouput on my machine (four physical cores and eight hyperthreaded):
Number of CPUs available = 8
Time for 1 thread = 11150 ms
Time for 4 thread = 4630 ms
Time for 8 thread = 2530 ms
Time for 12 thread = 2530 ms
Time for 24 thread = 2540 ms
According to my CPU this result seems correct, but my CPU usage never exceeds 13%.
I found the following Stack Overflow post, but I did not really find an answer to my question.
Instead of calling Thread.run(), which implements what your thread does, you should call Thread.start(), which will create a new thread and call run() on that new thread.
Now you are running run() on your main thread, without making a new thread. Since you have 13% CPU load, I expect you have 8 cores (meaning you have fully filled a single core).
Even better would be to create a custom implementation of the interface Runnable, instead of extending Thread. You can then run it on a thread as follows:
Thread t = new Thread(new MyRunnableTask());
t.start();
This is the common way because it gives you the flexibility (later on) to use more advanced mechanisms, such as ExecutorService.
EDIT:
As also noted in some of the comments. You are also changing the same variables (the static ones in Work) from several threads. You should never do this, because it allows for race conditions. For instance incrementing a variable can cause one, as explained here.
Thank you all for answering my question:
Yes, the JVM does not calculate the Math.cos(2.1545); on each iteration, so as said I've tried with Math.cos(i); on the original programme and there is a big difference!
And for the multi Thread, as said, I've created a custom implementation of the interface Runnable, instead of extending Thread and now use the Start(); method instead of run();
I now use the join method to wait until thread finish and remove the static variable.
Now the program use the full CPU load with the correct number of threads.
Just for information, here is my new code for the work class:
public class Work {
private Thread[] threadArray; //An array to store a specified number of new threads in the constructor
/**
*
* The constructor, set to the number Of threads to run
* #param numberOfThreads
*/
public Work(int numberOfThreads)
{
threadArray = new Thread[numberOfThreads];
}
/**
*
* A methode that launch a specified number of threads in the constructor of the class, and distributes the a number of iteration of each thread.
* the methode wait until each thread complete their task and print the time needed for all thread to complette their task.
* #param itterationForAllThread --> the total of itteration to do by all thread
*/
public void goWork(int itterationForAllThread)
{
long time = 0; // A variable used to compute the elapsed time
int itterationPerThread; // A variable that store the number of itterations Per Thread to do
itterationPerThread = itterationForAllThread/threadArray.length; //Divide the given number of itteration by the number of tread specified in the constructor
for(int i=0; i<threadArray.length; i++) //Launch the specified number of threads
{
threadArray[i] = new Thread(new T1(itterationPerThread)); //Create a new thread
threadArray[i].start(); //Start the job
}
long before = System.currentTimeMillis();
for (Thread thread : threadArray) //For each thread wait until it finish
{
try {
thread.join(); //Wait for the thread as finish
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
long after = System.currentTimeMillis();
time = after - before; //Compute the time elapsed
System.out.println("Time for " + threadArray.length + " Thread = " + time + " ms"); //Display the total time for the number of threads
}
}
And here the T1 class:
public class T1 implements Runnable{
private int iterrattionPerThread;
T1(int iterrattionPerThread)
{
this.iterrattionPerThread=iterrattionPerThread;
}
#Override
public void run()
{
for(int i=0; i<iterrattionPerThread; i++) //Get the thread busy with a number of iterations
{
Math.cos(i); //Do something that the JVM can not cache and need to be recaculated every iteration
}
}
}
From reading on Stack Overflow I've seen that many of you don't recommend using Timer Task. Hmmm... but I already implemented this:
I have this code:
detectionHandlerTimer.schedule(myTimerTask, 60 * 1000, 60 * 1000);
The thing is that work of myTimerTask lasts some time.
I would like this behavior:
wait 60 sec.
do task for some time (e.g. 40 - 100 sec).
task finished.
wait 60 seconds.
do task for some time (e.g. 40 - 100 sec).
But the code above behaves like this
wait 60 sec.
do task for some time (e.g. 40 - 100 sec).
task finished
do task for some time (e.g. 40 - 100 sec).
Because the time duration of task is bigger than 60, timer starts task immediately after task is finished. But I would like it to wait again.
This works. The key is to have the task itself (after it completes) schedule the next occurrence of the task.
import java.util.Timer;
import java.util.TimerTask;
public class TaskManager {
private Timer timer = new Timer();
public static void main(String[] args) {
TaskManager manager = new TaskManager();
manager.startTask();
}
public void startTask() {
timer.schedule(new PeriodicTask(), 0);
}
private class PeriodicTask extends TimerTask {
#Override
public void run() {
System.out.println(System.currentTimeMillis() + " Running");
/* replace with the actual task */
try {
Thread.sleep(15 * 1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
/* end task processing */
System.out.println(System.currentTimeMillis() + " Scheduling 10 seconds from now");
timer.schedule(new PeriodicTask(), 10 * 1000);
}
}
}
Which prints:
$ javac TaskManager.java && java TaskManager
1288282514688 Running
1288282529711 Scheduling 10 seconds from now
1288282539712 Running
1288282554713 Scheduling 10 seconds from now
1288282564714 Running
Here's what it looks like if you extract the second components of the timestamps (for clarity):
$ javac TaskManager.java && java TaskManager
14 Running
29 (+15 seconds execution) Scheduling 10 seconds from now
39 (+10 seconds delay until next run) Running
54 (+15 seconds execution) Scheduling 10 seconds from now
64 (+10 seconds delay until next run) Running
Just replace the 10s with 60s.