Synchronized Block inside the run method - java

Does using a synchronized block inside the run method makes any sense? I thought it does, as long as I'm using a relevant lock, not the instance of Runnable containing this run method. Reading the answers to similar questions on stackoverflow seemed to confirm this. I tried to write some simple code to test it and the synchronized block inside the run method doesn't prevent from data corruption:
public class Test {
public Test() {
ExecutorService es = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
es.execute(new Runnable() {
#Override
public void run() {
synchronized (lock) {
sum += 1;
}
}
});
}
es.shutdown();
while(!es.isTerminated()) {
}
}
private int sum = 0;
private final Object lock = new Object();
public static void main(String[] args) {
Test t = new Test();
System.out.println(t.sum);
}
}
Why this code generates incorrect results? Is this because the synchronized block or some other mistake? I feel like I'm missing something basic here.

It's possible your executor encounters some sort of unexpected error. If that happens you won't know it because you are not getting any return value to check.
Try switching to submit() instead of execute() and store a list of Future instances the Executor gives you. If the final sum is less than 1000, iterate the futures and get() each one. If an exception is raised you'll see what happened with that particular runnable task.

Apart from your simple example, which looks OK, you should be careful with synchronization in Runnables to prevent them from blocking each other when one Runnable waits for some resource to be released only by another Runnable later in the queue that has not started yet and never will since the current waiting Runnable must finish first.
With enough worker Threads executing the jobs this is less likely to occur, though.

Related

Why this Future's method is blocking main thread?

ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> calculate(Integer input) {
return executor.submit(() -> {
Thread.sleep(3000);
return input * input;
});
}
public static void main(String []args) throws Exception {
Main m = new Main();
System.out.println(m.calculate(5).get());
System.out.println("Main");
We submit Callable to Executor with 2 threads, but when i tell m.calculate(5).get() it block main thread.
So, I can't understand, when and why should I use Future if it blocks the main thread and doesn't run asynchronously?
If you look into the documentation of Future::get it says: "Waits if necessary for the computation to complete, and then retrieves its result." By calling this method you agree to wait for the result in the main thread.
You can check if Future has completed by calling Future::isDone, which returns boolean.
In your scenario it can be used like this
public static void main(String []args) throws Exception {
Main m = new Main();
Future<Integer> futureInt = m.calculate(5);
// do some other asynchronous task or something in main thread while futureInt is doing its calculations
// and then call Future::get
int result = futureInt.get();
See: doc
Future is indeed a very limited abstraction, in more realistic cases you should use CompletableFuture instead. Future is a pretty old class (since java 1.5 I guess) so the understanding of the industry has gradually evolved in the field of concurrent programming,
Nevertheless, it can still be useful by itself.
What if instead of spawning one future and immediately calling get on it, we would like to spawn many tasks and store the result in some list:
List<Future<Integer>> futures = new ArrayList<>(10);
for(int i = 0 ; i< 10; i++) {
futures.add(calculate(<some_integer>));
}
// at this point all futures are running concurrently
for(int i = 0 ; i < 10; i++) {
futures.get(i).get(); // will either return immediately or we'll block the main thread but the point is that all the calculations will run concurrently
}

Java using wait/notify methods on threads that do same thing

I was trying to understand the monitor on Java and the question that came to me is how to make the threads that run the same synchronized method to wait?
I was trying to make a simple program that would make 3 threads to use the same method to add to N element 1 for total of 10 000 times and I was wondering how to make other threads to wait when one is doing adding method and notifyAll after it is done if I would start all of them at the same time.
Here is my program that I wrote without wait/notify functions :
class Swapper implements Runnable{
int number;
Swapper(int number){
this.number=number;
}
#Override
public void run() {
while (mainClass.counter>0){
mainClass.incArrayElement(number);
}
}
}
public class mainClass {
public static volatile int counter = 10000;
public static volatile int[] testArray = new int[]{0,0,0};
public static synchronized void incArrayElement(int index){
if (counter>0) {
testArray[index - 1]++;
counter--;
}
else {
return;
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Swapper(1));
Thread thread2 = new Thread(new Swapper(2));
Thread thread3 = new Thread(new Swapper(3));
thread1.start();
thread2.start();
thread3.start();
thread1.join();
thread2.join();
thread3.join();
int checkSum = 0;
for (int i = 0; i < testArray.length; i++) {
System.out.println(testArray[i]);
checkSum+=testArray[i];
}
System.out.println(checkSum);
}
}
When a thread calls the synchronized method 'incArrayElement' of your class it acquires the lock of that object, any new thread cannot call ANY synchronized method of the same object as long as previous thread which had acquired the lock does not release the lock. Hence all other threads will be blocked until the execution is complete.
So why do you need to have the threads to call wait() as they are blocked already and waiting.
Unfortunately your example is not well chosen.
The method declared synchronized is controlled in a way that other threads cannot call it unless it has finished execution. Then one of the threads calls this method again. 'Which thread' cannot really be told because you have no control over it. Using wait and notify functions will not give you control over this neither. So if that is what you are looking for, you cannot achieve what you want. It will remain indeterministic for you.
If simply assuring that the method is called by only one thread at a time, then you already have that behavior, no need for wait or notify.

What happens if a Runnable executed several times in an ExecutorService

What happens if a thread has been executed same time more than once. Lets say I have thread like
private Runnable mySampleThread() {
return new Runnable() {
#Override
public void run() {
//something is going on here.
}
};
}
And I created an ExecutorService with fixed thread pool of 10. What happens if I execute mySampleThread 10 times in this ExecutorService.
Something like below,
ExecutorService mySampleExecutor = Executors.newFixedThreadPool(10);
while (i <= 10) {
mySampleExecutor.execute(mySampleThread);
i++;
}
Answer is very simple. Executor will execute Runnable object (it's not the Thread object) as described in documentation Interface Executor
Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation.
Basically, Executor will pick up one thread of it's internal pool (ThreadPoolExecutor), assign runnable to it a execute run() method.
Firstly elaborate your problem or query.
Nevertheless, assuming that you are calling the method "mySampleThread()" without missing brackets. This method actually returns a new Runnable object every time, so you are passing a new runnable all 10 times to executor. And it means you are submitting 10 different tasks to executor. So if executor creates different thread for every task (that depends upon its implementation), then whatever you code inside run() will be executed 10 times in 10 different threads.
And as described in other answers, the runnable object being passed to executor is not a thread.
Hope it clarifies.
By the way, you may try running the program.
As other answers clearly state, there will be as many new threads as the number of calls (might be less due to used executor, I'm focusing on Runnable reusage, limiting number of threads with executor is well explained in other answers). All of them created with single Runnable object.
What's worth mentioning, and I personally made use of this quite a few times - this is one of the ways to share data between multiple threads as all of these threads share Runnable that was used for creation. Synchronization issues come into play at this point, but that's another story.
Here's code to show the typical usage and the aforementioned synchronization problem.
import java.util.concurrent.ExecutorService;
class MyThread implements Runnable {
public int counter = 0;
#Override
public void run() {
for (int i = 0; i < 10000; i++) {
counter++;
}
}
}
class MySynchronizedThread implements Runnable {
public int counter = 0;
#Override
public void run() {
for (int i = 0; i < 10000; i++) {
synchronized (this) {
counter++;
}
}
}
}
public class RunnableTest {
public static void main(String[] args) throws InterruptedException {
MyThread runnableObject = new MyThread();
ExecutorService ex = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
ex.execute(runnableObject);
}
ex.shutdown();
ex.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
System.out
.println("Without synchronization: " + runnableObject.counter);
MyThread runnableSynchronizedObject = new MyThread();
ExecutorService ex2 = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
ex2.execute(runnableSynchronizedObject);
}
ex2.shutdown();
ex2.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
System.out.println("Without synchronization: "
+ runnableSynchronizedObject.counter);
}
}
There will be no differences in mySampleExecutor.execute(mySampleThread);, mySampleThread method return a new Runnable object. every thread will have it's own Frames

Run 3 threads and wait in Java

I'm trying to write a class that can only run X(Let's say 3)threads at one time. I have 8 threads that need to execute but I only want to allow 3 to run at once, then wait. Once one of the currently running threads stops, then it will start another. I'm not quite sure how to do this. My code looks like this:
public class Main {
public void start() {
for(int i=0; i<=ALLTHREADS; i++) {
MyThreadClass thread = new MyThreadClass(someParam, someParam);
thread.run();
// Continue until we have 3 running threads, wait until a new spot opens up. This is what I'm having problems with
}
}
}
public class MyThreadClass implements Runnable {
public MyThreadClass(int param1, int param2) {
// Some logic unimportant to this post
}
public void run() {
// Generic code here, the point of this is to download a large file
}
}
As you can see above most of it is stubbed out pseudo-code. I can post it if anyone would like but it's unimportant to the main question.
you should use thread pooling mechanism here to run multiple threads.
to make it easy we can go for thread pool executor in java which is very easy
create a fixed pool of 3 threads using executors method.
write a for loop for 8 iteration and call execute on each thread and it will run only 3 threads at a time.
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 0; i < 8; i++) {
Task task = new Task(someParam, someParam);
executor.execute(task);
}
executor.shutdown();
Unless this is homework, you can use Executors.newFixedThreadPool(3) which returns an ExecutorService with a max of 3 threads to perform Runnable tasks.

Java Concurrency in Practice: race condition in BoundedExecutor?

There's something odd about the implementation of the BoundedExecutor in the book Java Concurrency in Practice.
It's supposed to throttle task submission to the Executor by blocking the submitting thread when there are enough threads either queued or running in the Executor.
This is the implementation (after adding the missing rethrow in the catch clause):
public class BoundedExecutor {
private final Executor exec;
private final Semaphore semaphore;
public BoundedExecutor(Executor exec, int bound) {
this.exec = exec;
this.semaphore = new Semaphore(bound);
}
public void submitTask(final Runnable command) throws InterruptedException, RejectedExecutionException {
semaphore.acquire();
try {
exec.execute(new Runnable() {
#Override public void run() {
try {
command.run();
} finally {
semaphore.release();
}
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
}
}
When I instantiate the BoundedExecutor with an Executors.newCachedThreadPool() and a bound of 4, I would expect the number of threads instantiated by the cached thread pool to never exceed 4. In practice, however, it does. I've gotten this little test program to create as much as 11 threads:
public static void main(String[] args) throws Exception {
class CountingThreadFactory implements ThreadFactory {
int count;
#Override public Thread newThread(Runnable r) {
++count;
return new Thread(r);
}
}
List<Integer> counts = new ArrayList<Integer>();
for (int n = 0; n < 100; ++n) {
CountingThreadFactory countingThreadFactory = new CountingThreadFactory();
ExecutorService exec = Executors.newCachedThreadPool(countingThreadFactory);
try {
BoundedExecutor be = new BoundedExecutor(exec, 4);
for (int i = 0; i < 20000; ++i) {
be.submitTask(new Runnable() {
#Override public void run() {}
});
}
} finally {
exec.shutdown();
}
counts.add(countingThreadFactory.count);
}
System.out.println(Collections.max(counts));
}
I think there's a tiny little time frame between the release of the semaphore and the task ending, where another thread can aquire a permit and submit a task while the releasing thread hasn't finished yet. In other words, it has a race condition.
Can someone confirm this?
BoundedExecutor was indeed intended as an illustration of how to throttle task submission, not as a way to place a bound on thread pool size. There are more direct ways to achieve the latter, as at least one comment pointed out.
But the other answers don't mention the text in the book that says to use an unbounded queue and to
set the bound on the semaphore to be equal to the pool size plus the
number of queued tasks you want to allow, since the semaphore is
bounding the number of tasks both currently executing and awaiting
execution. [JCiP, end of section 8.3.3]
By mentioning unbounded queues and pool size, we were implying (apparently not very clearly) the use of a thread pool of bounded size.
What has always bothered me about BoundedExecutor, however, is that it doesn't implement the ExecutorService interface. A modern way to achieve similar functionality and still implement the standard interfaces would be to use Guava's listeningDecorator method and ForwardingListeningExecutorService class.
You are correct in your analysis of the race condition. There is no synchronization guarantees between the ExecutorService & the Semaphore.
However, I do not know if throttling the number of threads is what the BoundedExecutor is used for. I think it is more for throttling the number of tasks submitted to the service. Imagine if you have 5 million tasks that need to submit, and if you submit more then 10,000 of them you run out of memory.
Well you only will ever have 4 threads running at any given time, why would you want to try and queue up all 5 millions tasks? You can use a construct similar to this to throttle the number of tasks queued up at any given time. What you should get out of this is that at any given time there are only 4 tasks running.
Obviously the resolution to this is to use a Executors.newFixedThreadPool(4).
I see as much as 9 threads created at once. I suspect there is a race condition which causes there to be more thread than required.
This could be because there is before and after running the task work to be done. This means that even though there is only 4 thread inside your block of code, there is a number of thread stopping a previous task or getting ready to start a new task.
i.e. the thread does a release() while it is still running. Even though its the last thing you do its not the last thing it does before acquiring a new task.

Categories