java threading lock variable properly - java

Thread A does:
class A{
public String value;
public void methodA(String value){ //lets say value="test"
this.value=value;
//some code
// Thread B interrupts
System.out.println(value); // prints "haha" but I want it to be "test"
}
}
Thread B does:
class B{
public void methodB(){
a.setValue("haha");
}
}
methodB and methodA are some kinds of listener methods, which are executed in separate Threads.
How can I make sure that value does not change, as long as methodA has not finished? But I want also that "haha" is assigned to value afterwards. So I want B to wait till A has finished methodA and then assign "haha" to value.

The easiest way is to use 'synchronized' keyword on method that change the value of a field.
For example we have class that stores the data:
public class Data {
String value = "";
public synchronized void setValue(String val) {
this.value = val;
System.out.println(val);
}
}
And then Threads only use this method to update the value. Only one thread at the time can execute this method (no interrupts).
If you want to propagate this on two methods (like I suppose is the case). You can use two options. Or use synchronized on both methods or use external lock object.
If you want to be sure, that for example thread A has to be first to execute, you can use CountDownLatch object, which will stop other threads until thread A won't decrement the latch.
There are many ways to handle synchronization. You should be more precise to what you want to achieve and what kind of scenario you want to handle. Like for example - Is a.setValue("haha") a method from class A?
I would also recommend to look at documentation about concurrency https://docs.oracle.com/javase/tutorial/essential/concurrency/ .

If you just want methodA() to complete before methodB() is called, then you should call both methods from the same thread. In general, if you want your program to do certain things in a certain order, the best way to accomplish it is
to do all of the things in a single thread.
On the other hand, you might want both threads to work in parallel most of the time, but there might be one particular point that you don't want thread B to pass until thread A gets there. The Java standard library provides a variety of different synchronization objects that you could use. E.g., java.util.concurrent.CountDownLatch.
Initialization:
CountDownLatch countDownLatch=new CountDownLatch(1);
threadA.start();
threadB.start();
Thread A:
doSomeStuff();
methodA();
countDownLatch.countDown();
doSomeMoreStuff();
ThreadB:
doSomeOtherStuff();
countDownLatch.await();
methodB();
doSomeMoreOtherStuff();
The doSomeStuff() and doSomeOtherStuff() calls could happen concurrently, and the doSomeMoreStuff() and doSomeMoreOtherStuff() calls could happen concurrently, but the methodA() and methodB() would be serialized in this case.

Related

synchronization mechanism in Java

I need to make sure I understand synchronization mechanism in java, here are couple scenarios Id like to ask about:
theres a list 'a':
List a
and there are two functions:
void foo(int i){
synchronized(a){
a.add(i);
}
}
int goo(){
return a.size();
}
If there are multiple threads running, and one of them uses synchronized code block in foo, can other threads at this time access goo (or more specifically, access 'a'?)? How about the opposite, if there is a thread accessing a at the momen through goo (which is unsynchronized), can a thread enter the synchronized block of foo? or is it going to wait on it?
Let there be:
void synchronized foo(){
// do stuff
notifyAll();
//do stuff
if(someStatement)
return;
wait();
//do stuff
}
Some thread enters foo and reaches wait block, it releases the key of 'this', right? Second thread enters foo, and reaches notifyAll, at this point the first thread who was waiting should wake up and continue the code of foo, but it doesnt make sense because the other thread is currently holding the key. So what will happen?
Let there be:
class A implements Runnable {
Thread b;
foo(){
b= new Thread(()-> { /*some lambda function*/};
b.start();
}
goo(){
//here I'd like to notify the thread of b, how do I do it?
}
}
What should I do if I want to notify a thread that I created with lambda function? this means I dont have a reference to it, but I do have a reference to object 'b'.
Thanks in advance.
This is me trying to learn java synchronization
If there are multiple threads running, and one of them uses synchronized code block in foo, can other threads at this time access goo (or more specifically, access 'a'?)? How about the opposite, if there is a thread accessing a at the momen through goo (which is unsynchronized), can a thread enter the synchronized block of foo? or is it going to wait on it?
Yes, multiple threads can access those methods at the same time currently, either way round.
However, this is not correct code: you need to synchronize access to a.size() on a in order to ensure that you see any updates to the data structure that occurred in goo. For example, foo might see a size of 0 even after you have added something into the list using foo.
So, you need to make the code such that two threads can't be in those blocks at the same time.

Running an object with a synchronized method and normal method, concurrently?

Is it just that two synchronised methods that can't run concurrently?
For example, someone codes 2 Java classes.
public class A {
public synchronized void a1(){
//do something }
public void a2(){
//do something }
public synchronized int a3(){
int var = 0;
//do something changing var
return var; } }
public class B {
public void b1(){
//do something
}
public synchronized int b2(){
int var = 0;
//do something changing var
return var;
}
public void b3(){
//do something
}
}
With a main method,
public static void main(String[] args){
A firstA = new A();
A secondA = new A();
B firstB = newB();
//create some threads that perform operations on firstA, secondA and first B and start them
}
Assuming they run in parallel and call methods on the created objects and also assuming that none of these methods are prevented by other mechanisms from running currently.
Out of the methods in the example I gave, are there any that cannot be run concurrently if called at the same time by 2 different threads?
By running concurrently I mean, they will be sequenced so that one will finish before the other starts.
Assuming that there is no other synchronization involved, the only calls that will be mutually excluded are:
firstA.a1() vs firstA.a1()
firstA.a1() vs firstA.a3()
secondA.a1() vs secondA.a1()
secondA.a1() vs secondA.a3()
firstB.b2() vs firstB.b2()
This is because synchronized blocks have to use the same lock for them to have an effect on each other. When you mark a whole method as synchronized, the lock object will be the value of this. So methods in firstA will be completely independent of methods of secondA or firstB, because they use different locks.
The methods in your code that aren't marked synchronized won't even attempt to acquire any lock at all, they can run whenever they want.
Please note that mutual exclusion is just one aspect of multithreading. For your programme to work correctly, you also have to consider things like visibility and safe publication.
Of course, the answer depends on what "something" you "do" when you "do something", and since you don't show that, no one can answer. That's what happens when you omit the significant information. Don't omit the significant information.
What we can say is that the synchronized methods in A do not use the same lock as the synchronized methods in B.
If multiple threads access the same data, then they must synchronize with each other. The only way for threads to synchronize with each other is to use the same means of synchronization. If that's the use of synchronized, then they must synchronize on the same monitor (lock). So if the A methods and B methods access the same data from different threads, and who can tell if they do from what you show? then they won't work as shown.
If any of the unsynchronized methods access the same data from different threads, and the part you didn't show does not have other effective synchronization means, then they won't work.
All this depends on what you decided not to show us.
All of them can run at the same time without inturrupting each other.
because each thread handles different instance, there's no need for them to wait to what so ever synconized method.

synchronization and synchronized block in java

I've got a few questions about synchronization in java.
public class A {
private int i;
public A (int t) { i = t; }
public synchronized void increment() {
i++;
}
public synchronized void decrement() {
i--;
}
}
Suppose I have a class implemented as above and I create an object (p) of type A.
I know there can only be one thread executing p.increment(), but is possible for another thread to execute p.decrement() at the same time ?
Thanks~
synchronized does not protect methods. synchronized does not protect objects. synchronized does one thing, and one thing only.
The way you wrote your increment method is actually just a shorthand way of writing this:
public void increment() {
synchronized(this) {
i++;
}
}
This longer way of expressing it make it clear that synchronized is operating on this.
So, the one thing that synchronized does is: The JVM will not allow two threads to be synchronized on the same object at the same time.
If you have an object, p, of type A, then the answer is "no". The JVM will not allow one thread to do the increment at the same time the other thread does the decrement because both threads would be trying to synchronize on the same object, p.
On the other hand, if you have one object p and another object q, both of type A, then one thread could be in a p.increment() call while another thread is in the q.decrement() call. That's because each thread would be synchronized on a different object, and that is allowed.
P.S.: synchronized actually does one other thing that pertains to the Java concept called "Happens Before". That's something you should learn about (Google is your friend) before you get much deeper into multi-threaded programming.
No. Using synchronized as a method modifier is equivalent to wrapping the method with synchronized(this).
No. the synchronized will not allow multiple threads to enter the methods for an instance of the object. Note if you have a p1 AND a p2 of class A you could have p1.increment() running at same time p2.decrement() (etc.) is running.
Actually since the value is wrapped into synchronized methods, it content is also synchronized so no, it won't be executed by another thread.
Note that it can be called by another thread.
Personally, if it is only a matter of decrements/increments, I wouldn't bother synchronizing and would simply use Atomic values.
See documentation

Understanding synchronized and implementing a queue

I make multiple web requests from an Android application I'm working on. I want all these requests to be processed one at a time in the order they arrive, does my below code do that?
The way I read and understand synchronized is that of all the threads I spin off, only one can be in any of the below methods at one time. For example, if a user tries to postPhoto in one thread and then immediately getData in another thread, the getData thread will have to wait until the postPhoto thread is finished before it starts getting data. Since all my web requests go through this class and all the methods are synchronized, that means they're essentially queued up correct?
public class Controller {
public synchronized static String getData(String url, String limit) { ... }
public synchronized static String postPhoto(String filepath, int server_id) { ... }
public synchronized static InputStream getPhoto(String thumbnailPath) { ... }
public synchronized static String createIncident(String name, String description) { ... }
public synchronized static String updatePerson() { ... }
synchronized static boolean verifyConnection(String response) { ... }
}
EDIT:
I probably should have mentioned that even though some of the above methods are called createIncident or updatePerson, all of them ONLY make httprequests, the code inside all of the methods is generally the same except for important minor variations. In other parts of my code, I spin off threads to call these methods, and that's the part I was asking about. Since those threads call these methods, thread B that is calling getData will have to wait until thread A finishes it's part of postPhoto.
It depends on your implementation as well.
Is your controller singleton or instance per thread?
do your methods use shared objects?
If singleton and methods sharing objects, then there is no guarantee for thread1 to run postPhoto and then immediately after that getData even if you call sequentially. Another thread may take the turn and start running in between thread1 calling those 2 methods.
Bear in mind, synchronized keyword locks on the class itself so at any time there will be only one method executing. No 2 synchronized methods will be run at the same time.
Yes, you are right. The combination of synchronized and static guarantees what you want.

Java synchronized methods question

I have class with 2 synchronized methods:
class Service {
public synchronized void calc1();
public synchronized void calc2();
}
Both takes considerable time to execute. The question is would execution of these methods blocks each other. I.e. can both methods be executed in parallel in different threads?
No they can't be executed in parallel on the same service - both methods share the same monitor (i.e. this), and so if thread A is executing calc1, thread B won't be able to obtain the monitor and so won't be able to run calc2. (Note that thread B could call either method on a different instance of Service though, as it will be trying to acquire a different, unheld monitor, since the this in question would be different.)
The simplest solution (assuming you want them to run independently) would be to do something like the following using explicit monitors:
class Service {
private final Object calc1Lock = new Object();
private final Object calc2Lock = new Object();
public void calc1() {
synchronized(calc1Lock) {
// ... method body
}
}
public void calc2() {
synchronized(calc2Lock) {
// ... method body
}
}
}
The "locks" in question don't need to have any special abilities other than being Objects, and thus having a specific monitor. If you have more complex requirements that might involve trying to lock and falling back immediately, or querying who holds a lock, you can use the actual Lock objects, but for the basic case these simple Object locks are fine.
Yes, you can execute them in two different threads without messing up your class internals but no they won't run in parallel - only one of them will be executed at each time.
No, they cannot be. In this case you might use a synchronized block instead of synchronizing the whole method. Don't forget to synchronize on different objects.

Categories

Resources