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());
}
}
Related
You might think that this question is duplicate of this one but no answers of that question helps me for understanding synchronized method in android. I searched a lot on google for understanding synchronized methods and i found some answer but they didn't help me to perfectly understand Synchronized methods because no answer has any perfect practical example.
I have tried to understand synchronized method by implement 2 synchronized methods in my code and executing them concurrently but i am failed in properly implementing them. So, please provide explanation of synchronized method with simple example so, others like me also can understand it simply and in a faster way.
UPDATE
I am not sure i am going in right direction or not but i have tried following code which have 2 synchronized methods.
synchronized void add() {
counter++;
Log.e("JK", String.valueOf(counter));
}
synchronized void minus() {
counter--;
Log.e("JK", String.valueOf(counter));
}
and i have called this methods in two different threads using below code.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
synchronized (counter++) {
add();
}
}
},500);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
minus();
}
},1000);
Synchronized method is a method which can be used by only one thread at a time.
Other threads will be waiting until the method will be released.
You should have only serious reasons to declare method as synchronized because such method decreases the productivity. The classic case of synchronized method usage is when several threads are using same resources i.e. change state of some object and it is needed to make sure only one thread performs it at a time, otherwise it will cause inconsistency. Also make sure to make synchronized method as small as possible, ideally reduce it to contain only operations which can manipulate common resources.
For example the class Reporter has common resource fileWriter. It writes to file some messages with information about authors.
class Reporter{
private FileWriter fileWriter;
public synchronized void addRecord(String author, String message) throws IOException {
fileWriter.write("\n<<<<<<<<<<>>>>>>>>>>\n");
fileWriter.write("Message written by:" + author + "\n");
fileWriter.write("Message content:" + message);
}
public Reporter(FileWriter fileWriter) {
this.fileWriter = fileWriter;
}
}
Suppose you are running this code from 2 different threads:
Reporter reporter = new Reporter("path/report");
...
Thread thread = new Thread(){
public void run(){
reporter.addRecord("John", "Hi");
}
}
thread.start();
Thread thread2 = new Thread(){
public void run(){
reporter.addRecord("Bill", "Hello");
}
}
thread2.start();
The result for synchronized method will be like this :
<<<<<<<<<<>>>>>>>>>>
Message written by:John
Message content:Hi
<<<<<<<<<<>>>>>>>>>>
Message written by:Bill
Message content:Hello
If method is not synchronized several threads may write to file simultanously, which can cause an unpredictable sequence in file, like this:
<<<<<<<<<<>>>>>>>>>>
<<<<<<<<<<>>>>>>>>>>
Message written by:John
Message written by:Bill
Message content:Hello
Message content:Hi
Synchronized method is a method which can be used by only one thread at a time. Other threads will be waiting until the method will be released. You should have only valid reasons to declare method as synchronized because such method decreases the productivity and performance.
I stumbled across this method in a project i am working on, and immediately thought that something is wrong. I had the feeling this can't be any proper idom for anything.
But i don't get the intentions and implications of this. Can this be refactored? Does the second synchronized make any sense - and isn't the third synchronized redundant/unnecessary?
I am just starting to get into advanced concurrent/threadsafe programming in java - a detailed explanation why this makes sense or no sense and why is much appreciated!
#Override
public synchronized void run() {
synchronized (this.market) {
synchronized (this.market.getWallet()) {
this.handler.handleEvent(new WalletLecherEvent(this, market,
market.leechWallet()));
}
}
}
thanks in advance
edit, in order to supply more context:
public class WalletLeecherWorker extends Worker {
private IAbstractMarketAPI market = null;
private Thread thread = null;
public WalletLeecherWorker(IEventHandler handler, IAbstractMarketAPI market) {
super(handler);
this.market = market;
}
public void startThread() {
if (thread != null)
return;
thread = new Thread(this);
thread.start();
}
public MARKETs getMarket() {
return this.market.getName();
}
#Override
public synchronized void run() {
synchronized (this.market) {
synchronized (this.market.getWallet()) {
this.handler.handleEvent(new WalletLecherEvent(this, market,
market.leechWallet()));
}
}
}
}
..and the method market.getWallet():
#Override
public Wallet getWallet() {
return this.wallet;
}
I think that the intention is to block all threads from getting old Wallets, thus wrongfully synchronized/ deprecated data - as long as this thread runs();
The code obtains the locks on the following objects:
this - Prevents multiple threads from calling run() on the same WalletLeecherWorker instance
this.market - Prevents the run() from proceeding if another thread has obtained a lock on it, which is a reasonable assumption considering that the market instance is probably shared
this.market.wallet - Same as previous
None of these are obviously unnecessary, except for the run() method being synchronized. It offers no protection beyond what the following synchronized block does. The code itself could be because of very fine grained locking being used, with this particular code needing to lock everything, whereas other code may lock only the wallet or the market and the wallet.
However this code can be error (and even deadlock) prone. If you lock the objects in the wrong order, you can get a deadlock. It's also not very readable as you see. It's also dubious to have a Thread as an instance variable of the class with a startThread() method. The code may not be broken, but it's certainly not very pretty.
I have a class that has the object "Card". This class keeps checking to see if the object is not null anymore. Only one other thread can update this object. Should I just do it like the code below? Use volatile?Syncronized? lock (which I dont know how to use really)? What do you recommend as easiest solution?
Class A{
public Card myCard = null;
public void keepCheck(){
while(myCard == null){
Thread.sleep(100)
}
//value updated
callAnotherMethod();
}
Another thread has following:
public void run(){
a.myCard = new Card(5);
}
What do you suggest?
You should use a proper wait event (see the Guarded Block tutorial), otherwise you run the risk of the "watching" thread seeing the reference before it sees completely initialized member fields of the Card. Also wait() will allow the thread to sleep instead of sucking up CPU in a tight while loop.
For example:
Class A {
private final Object cardMonitor = new Object();
private volatile Card myCard;
public void keepCheck () {
synchronized (cardMonitor) {
while (myCard == null) {
try {
cardMonitor.wait();
} catch (InterruptedException x) {
// either abort or ignore, your choice
}
}
}
callAnotherMethod();
}
public void run () {
synchronized (cardMonitor) {
myCard = new Card(5);
cardMonitor.notifyAll();
}
}
}
I made myCard private in the above example. I do recommend avoiding lots of public fields in a case like this, as the code could end up getting messy fast.
Also note that you do not need cardMonitor -- you could use the A itself, but having a separate monitor object lets you have finer control over synchronization.
Beware, with the above implementation, if run() is called while callAnotherMethod() is executing, it will change myCard which may break callAnotherMethod() (which you do not show). Moving callAnotherMethod() inside the synchronized block is one possible solution, but you have to decide what the appropriate strategy is there given your requirements.
The variable needs to be volatile when modifying from a different thread if you intend to poll for it, but a better solution is to use wait()/notify() or even a Semaphore to keep your other thread sleeping until myCard variable is initialized.
Looks like you have a classic producer/consumer case.
You can handle this case using wait()/notify() methods. See here for an example: How to use wait and notify in Java?
Or here, for more examples: http://www.programcreek.com/2009/02/notify-and-wait-example/
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.
I have a static method with the following signature:
public static List<ResultObjects> processRequest(RequestObject req){
// process the request object and return the results.
}
What happens when there are multiple calls made to the above method concurrently? Will the requests be handled concurrently or one after the other?
Answering exactly your question:
Method will be executed concurrently (multiple times in the same time if you have several threads).
Requests will be handled concurrently.
You need to add the synchronized modifier if you are working with objects that require concurrent access.
All your calls to the method will be executed concurrently... but:
You may have concurrency issue (and being in non thread-safe situation) as soon as the code of your static method modify static variables. And in this case, you can declare your method as synchronized
If your method only use local variables you won't have concurrency issues.
If you need to avoid concurrent execution, you need to explicitly synchronize. The fact that the method is static has nothing to do with it. If you declare the method itself to be synchronized, then the synchronization will be on the class object. Otherwise you will need to synchronize on some static object (since this doesn't exist for static methods).
I see a lot of answers but none really pointing out the reason.
So this can be thought like this,
Whenever a thread is created, it is created with its own stack (I guess the size of the stack at the time of creation is ~2MB). So any execution that happens actually happens within the context of this thread stack.
Any variable that is created lives in the heap but it's reference lives in the stack with the exceptions being static variables which do not live in the thread stack.
Any function call you make is actually pushed onto the thread stack, be it static or non-static. Since the complete method was pushed onto the stack, any variable creation that takes place lives within the stack (again exceptions being static variables) and only accessible to one thread.
So all the methods are thread safe until they change the state of some static variable.
You can check it yourself:
public class ConcurrentStatic {
public static void main(String[] args) {
for (String name: new String[] {"Foo", "Bar", "Baz"}) {
new Thread(getRunnable(name)).start();
}
}
public static Runnable getRunnable(final String name) {
return new Runnable() {
public void run() {
longTask(name);
}
};
}
public static void longTask(String label) {
System.out.println(label + ": start");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(label + ": end");
}
}
all method invocations from separate threads in java are concurrent by default.