Why threads run sequentially instead of simulatenously in Java - java

The threads in the following code don't seem to run simultaneously. However if I change the number to 1 million or add a Thread.sleep(50); into the loop it runs simultaneously. Making the thread sleep produces homogeneous results while increasing number to one million makes each thread prints 50+ lines before switching to other thread. What is the exact reason for this?
class RunnableDemo implements Runnable {
int number = 4;
private Thread t;
private String threadName;
RunnableDemo(String name) {
threadName = name;
}
public void run() {
System.out.println("----------");
for (int i = number; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
}
}
public void start() {
System.out.println("Starting " + threadName);
t = new Thread(this, threadName);
t.start();
}
}
public class Test {
public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo("Thread-1");
RunnableDemo R2 = new RunnableDemo("Thread-2");
R1.start();
R2.start();
}
}
This is the output produced by the code when number is 4:
Starting Thread-1
Starting Thread-2
----------
Thread: Thread-1, 4
Thread: Thread-1, 3
Thread: Thread-1, 2
Thread: Thread-1, 1
----------
Thread: Thread-2, 4
Thread: Thread-2, 3
Thread: Thread-2, 2
Thread: Thread-2, 1

System.out.println is buffered. You cannot therefore use it to test thread simultaneity.

Let's assume your machine has a single processor. Only one thread can run at any one time. If multiple processes are running they each receive a slice of time on the processor and will then be swapped out by some scheduling algorithm.
In your case when the number is 4 a thread can complete its work before being swapped out. Once done any other thread in the waiting state can run.
T1 > starts > executes > terminates
T2 > starts > executes > terminates
When you increase the number to a million a thread can execute only part of its work in the time allocated by the scheduler. Once this time is up it will be swapped out by the scheduler and another thread in the waiting state will run.
T1 > starts > executes for time x > moved to waiting state
T2 > starts > executes for time x > moved to waiting state
T1 > resumes > executes for time x > moved to waiting state
T2 > resumes > executes for time x > moved to waiting state
......
T1 > terminates
T2 > terminates
Simarily, when you request your thread sleeps for x then another thread can be moved to the running state.
http://tinyurl.com/o8f3ogx

Threads don't neccessarily switch after each instruction. It is perfectly possible for a thread to execute entire loop before switching to another. Adding sleep prolongs the execution and increases likelihood of context switch.

Related

Java method with threads invocation and return in the end

I have created a simple class in Java with a method that invoke 2 thread (each thread has a simple loop with a println and a pause in each iteration).
In the method "mymethod" I've created and started my two threads.
Between Threads invocation, I've placed two prints. Print occur before threads end, and I assume that the order is as follows:
first print
first thread start
second thread start
second print
third print
Why the last instruction is executed only when all threads finish their computation instead to return 0 (last instruction)?
Obviously I know that this makes sense, but the return is an instruction like all others? Is the JVM that preventing the return if not all threads are finished yet?
public class Main {
public int mymethod (){
System.out.println("start");
Th t1 = new Th(); //this is a my thread instance
t1.start();
System.out.println("started th1");
Th t2 = new Th();
t2.start();
System.out.println("started th2");
System.out.println("Finished");
return 0;
}
public static void main(String[] args) {
// write your code here
Main m = new Main();
m.mymethod();
}
}
This is the output:
start
started th1
started th2
Finished
0
0
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
Process finished with exit code 0

Why did CyclicBarrier.await(int timeout,TimeUnit unit) didn't throw TimeOutException here?

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

Java ScheduledExecutorService not triggered when another performance-intensive thread is running

I have a Java application which consists of three main threads:
The main thread handling the user input, and starting the following threads.
The thread which computes something, utilizes the CPU at 70-80%.
The "monitor" thread, which should run in every 2 seconds, and read 1 short line from a file.
My issue is that the 3rd thread is not running properly. It starts to execute at the same time when the 2nd does, but in the meanwhile gets suspended, and gets resumed only after the 2nd thread finished.
I'm using ExecutorService for the 2nd thread, and ScheduledExecutorService for the monitoring thread. Here is my code:
ExecutorService executorService = Executors.newSingleThreadExecutor();
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
public void startThreads() {
startMonitorThread();
startCPUIntensiveThread();
}
public void startMonitorThread() {
System.out.println("### Monitor started");
Runnable monitor = () -> {
readFileContent()
System.out.println("hello from monitor");
};
// run the monitor in every 2s
scheduledExecutorService.scheduleAtFixedRate(monitor, 0, 2, TimeUnit.SECONDS);
System.out.println("### Monitor scheduled");
}
public void startCPUIntensiveThread() {
Runnable runBenchmark = () -> {
try {
MyBenchmarkRunner.runBenchmark(); // runs 5 iterations, each takes 4 seconds
} catch (Exception e) {
System.err.println("Benchmark failed. See the log for more details.");
}
};
executorService.submit(runBenchmark);
}
And the output:
### Monitor started
### Monitor scheduled
hello from monitor // monitor scheduled and executed
===== Running benchmark iteration 1 =====
===== Running benchmark iteration 2 =====
===== Running benchmark iteration 3 =====
===== Running benchmark iteration 4 =====
===== Running benchmark iteration 5 ===== // at least 20 seconds passed
hello from monitor // monitor executed again, but it should have been executed 2x during each benchmark iteration
hello from monitor
How should I modify the code to ensure that the monitor thread is called in every 2 seconds?

Java - Semaphore release without acquire

I have threads which are given random number (1 to n) and are instructed to print them in sorted order. I used semaphore such that I acquire the number of permits = random number and release one permit more than what was acquired.
acquired = random number; released = 1+random number
Initial permit count for semaphore is 1. So thread with random number 1 should get permit and then 2 and so on.
This is supported as per the documentation given below
There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire().
The problem is my program gets stuck after 1 for n>2.
My program is given below:
import java.util.concurrent.Semaphore;
public class MultiThreading {
public static void main(String[] args) {
Semaphore sem = new Semaphore(1,false);
for(int i=5;i>=1;i--)
new MyThread(i, sem);
}
}
class MyThread implements Runnable {
int var;Semaphore sem;
public MyThread(int a, Semaphore s) {
var =a;sem=s;
new Thread(this).start();
}
#Override
public void run() {
System.out.println("Acquiring lock -- "+var);
try {
sem.acquire(var);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(var);
System.out.println("Releasing lock -- "+var);
sem.release(var+1);
}
}
Output is :
Acquiring lock -- 4
Acquiring lock -- 5
Acquiring lock -- 3
Acquiring lock -- 2
Acquiring lock -- 1
1
Releasing lock -- 1
While If I modify my code with tryAcquire, it runs perfectly well.
Below is new run implementation
#Override
public void run() {
boolean acquired = false;
while(!acquired) {
acquired = sem.tryAcquire(var);
}
System.out.println(var);
sem.release(var+1);
}
Can someone please explain the semaphore's permit acquire mechanism when mulitple threads are waiting with different permit request??
It's a clever strategy, but you're misunderstanding how Sempahore hands out permits. If you run your code enough times you'll actually see it reach step two:
Acquiring lock -- 5
Acquiring lock -- 1
1
Releasing lock -- 1
Acquiring lock -- 3
Acquiring lock -- 2
2
Acquiring lock -- 4
Releasing lock -- 2
If you keep on re-running it enough times you'd actually see it successfully finish. This happens because of how Semaphore hands out permits. You're assuming Semaphore will try to accommodate an acquire() call as soon as it has enough permits to do so. If we look carefully at the documentation for Semaphore.aquire(int) we'll see that is not the case (emphasis mine):
If insufficient permits are available then the current thread becomes disabled for thread scheduling purposes and lies dormant until ... some other thread invokes one of the release methods for this semaphore, the current thread is next to be assigned permits and the number of available permits satisfies this request.
In other words Semaphore keeps a queue of pending acquire request and, upon each call to .release(), only checks the head of the queue. In particular if you enable fair queuing (set the second constructor argument to true) you'll see even step one doesn't occur, because step 5 is (usually) the first in the queue and even new acquire() calls that could be fulfilled will be queued up behind the other pending calls.
In short this means you cannot rely on .acquire() to return as soon as possible, as your code assumes.
By using .tryAcquire() in a loop instead you avoid making any blocking calls (and therefore put a lot more load on your Semaphore) and as soon as the necessary number of permits becomes available a tryAcquire() call will successfully obtain them. This works but is wasteful.
Picture a wait-list at a restaurant. Using .aquire() is like putting your name on the list and waiting to be called. It may not be perfectly efficient, but they'll get to you in a (reasonably) fair amount of time. Imagine instead if everyone just shouted at the host "Do you have a table for n yet?" as often as they could - that's your tryAquire() loop. It may still work out (as it does in your example) but it's certainly not the right way to go about it.
So what should you do instead? There's a number of possibly useful tools in java.util.concurrent, and which is best somewhat depends on what exactly you're trying to do. Seeing as you're effectively having each thread start the next one I might use a BlockingQueue as the synchronization aid, pushing the next step into the queue each time. Each thread would then poll the queue, and if it's not the activated thread's turn replace the value and wait again.
Here's an example:
public class MultiThreading {
public static void main(String[] args) throws Exception{
// Use fair queuing to prevent an out-of-order task
// from jumping to the head of the line again
// try setting this to false - you'll see far more re-queuing calls
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(1, true);
for (int i = 5; i >= 1; i--) {
Thread.sleep(100); // not necessary, just helps demonstrate the queuing behavior
new MyThread(i, queue).start();
}
queue.add(1); // work starts now
}
static class MyThread extends Thread {
int var;
BlockingQueue<Integer> queue;
public MyThread(int var, BlockingQueue<Integer> queue) {
this.var = var;
this.queue = queue;
}
#Override
public void run() {
System.out.println("Task " + var + " is now pending...");
try {
while (true) {
int task = queue.take();
if (task != var) {
System.out.println(
"Task " + var + " got task " + task + " instead - re-queuing");
queue.add(task);
} else {
break;
}
}
} catch (InterruptedException e) {
// If a thread is interrupted, re-mark the thread interrupted and terminate
Thread.currentThread().interrupt();
return;
}
System.out.println("Finished task " + var);
System.out.println("Registering task " + (var + 1) + " to run next");
queue.add(var + 1);
}
}
}
This prints the following and terminates successfully:
Task 5 is now pending...
Task 4 is now pending...
Task 3 is now pending...
Task 2 is now pending...
Task 1 is now pending...
Task 5 got task 1 instead - re-queuing
Task 4 got task 1 instead - re-queuing
Task 3 got task 1 instead - re-queuing
Task 2 got task 1 instead - re-queuing
Finished task 1
Registering task 2 to run next
Task 5 got task 2 instead - re-queuing
Task 4 got task 2 instead - re-queuing
Task 3 got task 2 instead - re-queuing
Finished task 2
Registering task 3 to run next
Task 5 got task 3 instead - re-queuing
Task 4 got task 3 instead - re-queuing
Finished task 3
Registering task 4 to run next
Task 5 got task 4 instead - re-queuing
Finished task 4
Registering task 5 to run next
Finished task 5
Registering task 6 to run next
The Javadoc for Semaphore.acquire(int) says:
If insufficient permits are available then the current thread becomes
disabled for thread scheduling purposes and lies dormant until one of
two things happens:
Some other thread invokes one of the release methods for this semaphore,
the current thread is next to be assigned permits and the number of
available permits satisfies this request [or the thread is interrupted].
The thread that is "next to be assigned" is probably thread 4 in your example. It is waiting until there are 4 permits available. However, thread 1, which gets a permit upon calling acquire(), only releases 2 permits, which is not enough to unblock thread 4. Meanwhile, thread 2, which is the only thread for which there are sufficient permits, is not the next to be assigned, so it doesn't get the permits.
Your modified code runs fine because the threads don't block when they try to get a semaphore; they just try again, going to the back of the line. Eventually thread 2 reaches the front of the line and is thus next to be assigned, and so gets its permits.

Restart thread once the threads inside it finished

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();
}

Categories