I was going through some simple examples on threading/synchronizing from a book that claims the use of synchronized will allow access to the method by one thread being called on the same instance. It does serialize as promised but it seems that about 9/10 times the third Caller created in the Synch main method below comes before the second. This code is the example code showing the issues without a synchronized method.
class CallMe {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("CallMe Interrupted");
}
System.out.println("]");
}
}
class Caller implements Runnable {
String msg;
CallMe target;
Thread t;
public Caller (CallMe target, String msg) {
this.target = target;
this.msg = msg;
t = new Thread(this);
t.start();
}
#Override
public void run() {
target.call(msg);
}
}
class Synch {
public static void main(String args[]) {
CallMe target = new CallMe();
Caller c1 = new Caller(target, "Hello");
Caller c2 = new Caller(target, "Synchronized");
Caller c3 = new Caller(target, "World");
try {
c1.t.join();
c2.t.join();
c3.t.join();
} catch (InterruptedException e) {
System.out.println("Synch Interrupted");
}
}
}
The book shows two ways to deal with the issue, they are -
synchronized void call(String msg) {...} and
public void run() { synchronized (target) {...} }
It's clear that both options work because, as opposed to the original code, the bracketed words are consistent like...
[Hello]
[World] (about 90% of the time the calls are backwards)
[Synchronized](1/many have Synchronized as the first msg)
...there's no rhyme or reason to the original code. So I know it's "working" and can be seen directly by placing breakpoints on each of the Caller instantiations. It works every time, obviously to me, when I do.
Why is the third Caller consistently calling call before the second?
Threads by definition run in parallel, and none is given precedence over any other.
Once the threads are all launched it is essentially random which will run first, in general the first one launched will have a slight "head start" but that head start is tiny compared to the overhead of launching threads etc.
A quirk of your particular environment just happens to be favoring one thread, the results may well vary on different systems and certainly shouldn't be relied on.
Incidentally this is bad practice for a number of reasons:
public Caller (CallMe target, String msg) {
this.target = target;
this.msg = msg;
t = new Thread(this);
t.start();
}
(You probably got a compiler warning in fact).
Much better is to provide a start method
public Caller start() {
t.start();
return this;
}
and then do
new Caller(target, msg).start();
This absolutely ensures that the Caller object is fully initialized and ready to go before the Thread starts processing it.
Why is the third call consistently calling call before the second?
It's not doing so consistently - it's doing so about 90% of the time.
Basically, synchronization isn't guaranteed to be first-in, first-out... and there's no guarantee that the calls will even be made in the order you're expecting. Three new threads are being started in quick succession - there is no guarantee about which thread will actually start executing its code first.
Fundamentally if you want to impose ordering on parallel code, you need to do so explicitly. Synchronization doesn't provide ordering - it only provides exclusivity.
It does serialize as promised but it seems that about 9/10 times the third Caller created in the Synch main method below comes before the second.
Be careful to understand the meaning of "serialize" in your sentence: it means that all the code sections protected by the same lock will never run in parallel; in other words, their execution will be serial.
What it doesn't mean is "execution of these code sections will occur in a strict, specified order". It will not.
Related
I am not very good at multithreading and am baffled by this code:
public class Main {
public static void main(String... args) throws Exception {
new Thread(Main::test).start();
}
private static synchronized void test() {
new Thread(Main::test).start();
System.out.println("TEST");
}
}
Can it result in a deadlock or not? If so, then why have I not been able to get it to deadlock? My thinking is, thread 1 acquires lock on test(), then another thread, created in test() tries to acquire it and they should be waiting on each other. But they aren't, why not?
I know, that adding join() in test() will make it result in a deadlock, but how come the example below doesn't use joins and deadlocks?
This code results in a deadlock literally every time I run it:
public class Main {
public static void main(String... args) {
new Thread(Main::test).start();
new Thread(Main::test2).start();
}
private static void test() {
synchronized (Integer.class) {
try {
Thread.sleep(1);
} catch (Exception e) {
}
synchronized (Float.class) {
System.out.println("Acquired float");
}
}
}
private static void test2() {
synchronized (Float.class) {
try {
Thread.sleep(1);
} catch (Exception e) {
}
synchronized (Integer.class) {
System.out.println("Acquired integer");
}
}
}
}
No, the code in the first example cannot deadlock. The newly started threads will simply wait until the previous thread exits the method to acquire the lock.
The code in the second example deadlocks because the locks are acquired in opposite order and because of the sleeps are reliably going to block each other.
When you're at the phase where you're first learning how to think about concurrency and related problems, I would very much recommend using physical props to keep your thoughts and hypotheses clear and explicit.
For example, grab a A3 sheet of paper, set up a "race track" where you use something like Monopoly pieces to signify what you're doing in your code, what you expect to happen, and what your experiments show actually happens.
When your experiments don't work out, take a small piece of the beginning first, and verify it. Then add some more, and so on.
It helps if you read about how actual computers (not the CS ideal or conceptual computers) currently work. How the CPU gets data out of the main memory into its cache. How two or three CPUs decide which one of them can handle data in one cache line at a time. Then, how the Java Memory Model needs you to write your source code so that the JVM knows what you actually mean to happen.
I'm doing a short course about Threads in Java, in one of my homeworks they asked me: ¿Why you don't should be synchronize the run method? show an example.
I searched about it, and that i think is use synchronized for a run method is not useful, at least commonly. Because the people don't call the run method manually, so the synchronized effect isn't visible creating multiple instances of a object with synchronized run.
So, i would like know if exist another reason or if i'm wrong.
Syncrhonizing the run() method of a Runnable is completely pointless unless you want to share the Runnable among multiple threads and you want to serialize the execution of those threads. Which is basically a contradiction in terms.
If the run method of a Runnable were synchronized, then either
a) you have many runnables (in which case, no need to synchronise, as each one is called on a different object), or else
b) you have one runnable being called in many threads - but then they clearly won't run in parallel -- thus defeating the purpose of having multiple threads!
You may synchronize on run method, nothing wrong with it. I think the reasons behind this advice should be explained to you by the instructor of course.
We need synchronization when there are shared resources (between threads).
Synchronizing on a method is same as synchronizing on this which will block other method calls.
As a counter example, a poor man's Future implementation;
public class SynchronizedRun {
static abstract class Future<T> implements Runnable{
private T value;
public synchronized T getValue(){
return value;
}
protected void setValue(T val){
value = val;
}
}
public static void main(String[] args) {
Future<Integer> longRunningJob = new Future<Integer> (){
#Override
synchronized public void run() {
try {
Thread.sleep(5000);
setValue(42);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(longRunningJob).start();
System.out.println("getting results");
System.out.println("result = " + longRunningJob.getValue());
}
}
Today I had to write a method which get a String as a parameter, make a new thread and write it out to the consol after 5 seconds waiting, so something like this:
public void exampleMethod(final String str){
Runnable myRunnable = new Runnable(){
public void run(){
try {
Thread.sleep(5000);
System.out.println(str);
} catch (InterruptedException e) {
//handling of the exception
}
}
};
Thread thread = new Thread(myRunnable);
thread.start();
//some other things to do
}
My question is: How can I test and what should I test in here with JUnit?
Thank you!
There is nothing complex in this method. You are only using standard API-methods: Thread.sleep, System.out.println, ...
The parameter is just printed, you don't modify it nor use it for a calculation or another method.
There are no side-effects to your own written code, just to the STL.
And there is no result of the method, which you could test.
In my opinion it is not necessary and not simply possible to test it.
The only thing you could test (and even that wouldn't be trivial), is, if after an amount of time the String is printed.
[...] JUnit finishes execution while the thread is still alive. There could have been problems down the line, toward the end of that thread's execution, but your test would never reflect it.
The problem lies in JUnit's TestRunner. It isn't designed to look for Runnable instances and wait around to report on their activities. It fires them off and forgets about them. For this reason, multithreaded unit tests in JUnit have been nearly impossible to write and maintain.
Well, the source - this article - is from 2003 and there's no guarantee that this hasn't been fixed yet, but you may try it out yourself.
My suggestion would be:
Run your code and measure the time it takes. Then add some 1000 milliseconds and but a Thread.sleep(executionTime+1000); after you started you asynchronous task. Not that elegant, but should work in practice. If you want more elegance here (and waste less time), you may want to look for framework that provide a solution.
...Or if you start your Thread directly in the test, you may also use Thread.join to wait, but you will have cases, where you aren't able to do that.
EDIT:
Also check this article, which could provide a solution to pipe those errors to the main thread:
public class AsynchTester{
private Thread thread;
private volatile Error error;
private volatile RuntimeException runtimeExc;
public AsynchTester(final Runnable runnable) {
thread = new Thread(new Runnable() {
#Override
public void run() {
try {
runnable.run();
} catch (Error e) {
error = e;
} catch (RuntimeException e) {
runtimeExc = e;
}
}
});
}
public void start() {
thread.start();
}
public void test() throws InterruptedException {
thread.join();
if (error != null)
throw error;
if (runtimeExc != null)
throw runtimeExc;
}
}
Use it like that:
#Test
public void test() throws InterruptedException {
AsynchTester tester = new AsynchTester(new Runnable() {
#Override
public void run() {
//async code
}
});
tester.start();
tester.test();
}
The issue here is that you are trying to test an interaction instead of a simple returned result or a state change. However, that does not mean it can't be done.
The standard out PrintStream can be replaced with System.setOut(). You can inject your own mock implementation that would allow you verify that the String was written to the stream. You just have to be careful, since this changes the global state, it might effect other code or tests that rely on standard output. At a minimum, you will have to put back the original stream. But things might get more complicated if tests are running in parallel.
This takes us to the next issue, the sleep. There isn't a strong guarantee to how long a sleep will block. This means your test would have to provide some buffer to ensure that the thread had time to write the String before checking the state of the mock stream. You don't want your test to be flaky because of some execution timing jitter. So you would have to decide what buffer you would consider acceptable.
An alternative approach would be to change the implementation of the code so that it is easier to test.
The simplest way to do this is to remove all the static dependencies. Instead of explicitly referencing System.out, the class could be initialized with with an PrintStream to write to. Additionally, you could define an interface that would wrap Thread.sleep(). For testing purposes, you can initialize the class with the mock stream and no-op implementation of the sleep interface. However, you may still have some timing issues as you need the newly created thread to execute before continuing the test.
The other thing you can do is take a step back and decide how much you care about this code being tested. There are only 4 interesting lines of code in this sample and none of them are complicated. Having a code review could be sufficient to ensure there are no bugs.
However, if the business logic is more complicate than writing to standard out, you might decided that testing that is important. The good news is that scheduling a task in an executor is straight forward and that is the part that is making the testing hard. You could make an abstraction that encompasses the scheduling of the task in a background thread. Then provide yourself with more direct access to the business logic in order to test that.
I have often solved that, by providing a ResultTarget which implements an interface IResultTarget to the thread,
In productive code the result will be a list that contains the calculation result. (or null)
In your unit test the ResultTarget is the unit test class itself, which then easily can check the received result.
public Interface IResultTarget {
List getResult();
}
public void ThreadTest extends TestCase implements IResultTarget {
List result;
public List getResult(
return this.result;
}
public void testThread() {
MyRunnable myRunnable= new MyRunnable ();
myRunnable.setResultTarget(this);
Thread thread = new Thread(myRunnable);
thread .start();
Thread.sleep(5 * 1000);
// expecting one element as result of the work of myRunnable.
assertEquals(1, result.size());
}
}
I'm looking for a clean design/solution for this problem: I have two threads, that may run as long as the user wants to, but eventually stop when the user issues the stop command. However if one of the threads ends abruptly (eg. because of a runtime exception) I want to stop the other thread.
Now both threads execute a Runnable (so when I say 'stop a thread' what I mean is that I call a stop() method on the Runnable instance), what I'm thinking is to avoid using threads (Thread class) and use the CompletionService interface and then submit both Runnables to an instance of this service.
With this I would use the CompletionService's method take(), when this method returns I would stop both Runnables since I know that at least one of them already finished. Now, this works, but if possible I would like to know of a simpler/better solution for my case.
Also, what is a good solution when we have n threads and as soon as one of them finishes to stop execution of all the others ?
Thanks in advance.
There is no Runnable.stop() method, so that is an obvious non-starter.
Don't use Thread.stop()! It is fundamentally unsafe in the vast majority of cases.
Here are a couple of approaches that should work, if implemented correctly.
You could have both threads regularly check some common flag variable (e.g. call it stopNow), and arrange that both threads set it when they finish. (The flag variable needs to be volatile ... or properly synchronized.)
You could have both threads regularly call the Thread.isInterrupted() method to see if it has been interrupted. Then each thread needs to call Thread.interrupt() on the other one when it finishes.
I know Runnable doesn't have that method, but my implementation of Runnable that I pass to the threads does have it, and when calling it the runner will finish the run() method (something like Corsika's code, below this answer).
From what I can tell, Corsika's code assumes that there is a stop() method that will do the right thing when called. The real question is how have you do implemented it? Or how do you intend to implement it?
If you already have an implementation that works, then you've got a solution to the problem.
Otherwise, my answer gives two possible approaches to implementing the "stop now" functionality.
I appreciate your suggestions, but I have a doubt, how does 'regularly check/call' translate into code ?
It entirely depends on the task that the Runnable.run() method performs. It typically entails adding a check / call to certain loops so that the test happens reasonably often ... but not too often. You also want to check only when it would be safe to stop the computation, and that is another thing you must work out for yourself.
The following should help to give you some ideas of how you might apply it to your problem. Hope it helps...
import java.util.*;
public class x {
public static void main(String[] args) {
ThreadManager<Thread> t = new ThreadManager<Thread>();
Thread a = new MyThread(t);
Thread b = new MyThread(t);
Thread c = new MyThread(t);
t.add(a);
t.add(b);
t.add(c);
a.start();
b.start();
c.start();
}
}
class ThreadManager<T> extends ArrayList<T> {
public void stopThreads() {
for (T t : this) {
Thread thread = (Thread) t;
if (thread.isAlive()) {
try { thread.interrupt(); }
catch (Exception e) {/*ignore on purpose*/}
}
}
}
}
class MyThread extends Thread {
static boolean signalled = false;
private ThreadManager m;
public MyThread(ThreadManager tm) {
m = tm;
}
public void run() {
try {
// periodically check ...
if (this.interrupted()) throw new InterruptedException();
// do stuff
} catch (Exception e) {
synchronized(getClass()) {
if (!signalled) {
signalled = true;
m.stopThreads();
}
}
}
}
}
Whether you use a stop flag or an interrupt, you will need to periodically check to see whether a thread has been signalled to stop.
You could give them access to eachother, or a callback to something that had access to both so it could interrupt the other. Consider:
MyRunner aRunner = new MyRunner(this);
MyRunner bRunner = new MyRunner(this);
Thread a = new Thread(aRunner);
Thread b = new Thread(brunner);
// catch appropriate exceptions, error handling... probably should verify
// 'winner' actually is a or b
public void stopOtherThread(MyRunner winner) {
if(winner == aRunner ) bRunner .stop(); // assumes you have stop on class MyRunner
else aRunner.stop();
}
// later
a.start();
b.start();
// in your run method
public void run() {
// la de da de da
// awesome code
while(true) fork();
// other code here
myRunnerMaster.stopOtherThread(this);
}
I have a method in java which calls webservice. Now if the webservice is taking more than 1 sec. of time. I should be able to kill the method and continue in the program flow.
Google Guava's SimpleTimeLimiter will do what you need, specifically its callWithTimeout() method.
I would recommend you to use the Executors framework and call Future.get(long, TimeUnit). As for killing that call, you can call Future.cancel(true). Of course, you'll have to submit a Callable that contains the call.
In case you don't want to add a new library, you can easily accomplish this by delegating the Web Service invocation to another Thread, and join on it using a timeout of 1 sec. Below is a complete program which does these tasks. There are 2 key points:
Use Asynchronous Thread to do the call and join on it with TimeOut. You can additionally set it as Daemon.
Convey to the Asynchronous thread when the value from operation doesn't need to be consumed, so that it doesn't make unnecessary assignments.
Code:
public class Main {
String returnVar;
private static final long TIME_OUT=1000;//in mills
private void makeCall() {
WebServiceStubDummy ws = new WebServiceStubDummy();
Boolean timeElapsed = false;
Thread t = new Thread(new AsyncWSCall(ws,timeElapsed));
t.start();
try {
t.join(TIME_OUT);
} catch (InterruptedException e) {}
synchronized (ws) {
timeElapsed=true;
}
System.out.println(returnVar);
}
private class AsyncWSCall implements Runnable{
WebServiceStubDummy ws;
Boolean timeElapsed;
public AsyncWSCall(WebServiceStubDummy ws, Boolean timeElapsed){
this.ws=ws;
this.timeElapsed=timeElapsed;
}
#Override
public void run() {
String myStr = ws.dummyMethod();
//synchronize for shared variable timeElapsed
synchronized (ws) {
if(!timeElapsed){
//if time elapsed don't assign
returnVar=myStr;
}
}
}
}
class WebServiceStubDummy{
public String dummyMethod(){
try {
//Dummy Call: if changed to 2000 value will not be consumed
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "From Dummy Metho";
}
}
/**
* #param args
*/
public static void main(String[] args) {
Main m=new Main();
m.makeCall();
}}
You can additionally fine tune your code as per how you wish to pass the WebService object and how you want to assign the result of WS operation
Use a timeout of 1 sec. on your webservice request.
The SO-thread "Killing thread after some specified time limit in java" could help. It makes use of ExecutorService
Time Limitation on method execution in java could also be used. Keep in mind though that Thread.stop is deprecated:
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock
all the monitors that it has locked. (The monitors are unlocked as the
ThreadDeath exception propagates up the stack.) If any of the objects
previously protected by these monitors were in an inconsistent state,
other threads may now view these objects in an inconsistent state.
Such objects are said to be damaged. When threads operate on damaged
objects, arbitrary behavior can result. This behavior may be subtle
and difficult to detect, or it may be pronounced. Unlike other
unchecked exceptions, ThreadDeath kills threads silently; thus, the
user has no warning that his program may be corrupted. The corruption
can manifest itself at any time after the actual damage occurs, even
hours or days in the future.
source: Java Thread Primitive Deprecation