Threads calling both static and non-static method - java

Disclaimer: This code is copied from synchronized blocks for static and non-static methods
I made some modification to it. I want to know how to make threads call both synchronized static and non-static methods. I can make it work by wrapping the non-static method in a synchronized block. Is there any other way?
public class StaticNonStaticSynch
{
public static void main(String[] args)
{
final StaticNonStaticTest staticNonStaticTest = new StaticNonStaticTest();
Runnable runnable1 = new Runnable()
{
#Override
public void run()
{
staticNonStaticTest.nonStaticMethod();
}
};
Runnable runnable2 = new Runnable()
{
#Override
public void run()
{
StaticNonStaticTest.staticMethod();
}
};
Thread thread1 = new Thread(runnable1, "First Thread");
Thread thread2 = new Thread(runnable2, "Second Thread");
thread1.start();
thread2.start();
}
}
class StaticNonStaticTest
{
void nonStaticMethod()
{
//synchronized (StaticNonStaticTest.class){
for(int i=0;i<50;i++)
{
System.out.println("Non - Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
// }
}
static synchronized void staticMethod()
{
for(int i=0;i<50;i++)
{
System.out.println("Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
}
}

Remember that this:
public class MyClass {
public synchronized void doSomething() {
// Do something
}
public synchronized static void doSomethingStatic() {
// Do something static
}
}
Essentially compiles to this:
public class MyClass {
public void doSomething() {
synchronized(this) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MyClass.class) {
// Do something static
}
}
}
Notice that they don't synchronize on the same thing. To fix this, create an object for both of them to lock on (known as a mutually exclusive object, or a "mutex"):
public class MyClass {
private static final Object MUTEX = new Object();
public void doSomething() {
synchronized(MUTEX) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MUTEX) {
// Do something static
}
}
}
That should make it so that only one of these two methods are running at the same time across multiple threads.
A couple tips:
Always use synchronized(variable) on a variable that's final.
The MUTEX doesn't have to be strictly a mutex, it could be an actual object. See the example below.
Remember how the synchronized modifier on methods is effectively implemented. It's just like a synchronized block on this or MyClass.class.
Besides having an object that's strictly a mutex, you can use any field that's final. For example, to synchronize on a Map during iteration:
public class MyClass {
private static final Map<String, String> map = new HashMap<String, String>(); // Java 6
private static final Map<String, String> map = new HashMap<>(); // Java 7
public static void put(String k, String v) {
synchronized(map) {
map.put(k, v);
}
}
public static void printAll() {
synchronized(map) {
for (Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
}
This code guarantees that you'll never get a ConcurrentModificationException

You can have both methods internally synchronize on a common lock object. Otherwise, the only way to have the instance method block while the static method executes is to synchronize on the class object (as you have in the commented lines).
Synchronized instance methods synchronize on the object instance; synchronized static methods synchronize on the class instance. Note that synchronized static methods might execute simultaneously if there are two instances of the class (say, from different class loaders). You usually would know if this is happening, because you have to do considerable work to make it happen.
Here's one way to synchronize both static and instance methods on a common lock object:
class StaticNonStaticTest {
private static final Object LOCK_OBJECT = new Object();
void nonStaticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Non - Static method called by "
+ Thread.currentThread().getName() + " : = " + i);
}
}
}
static void staticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Static method called by "
+ Thread.currentThread().getName() +" : = "+i);
}
}
}
}

Related

java thread synchronized & lock no effect?

so much confused why I get a random result while doing 'i++' in a synchronized or a locked method?
public class aaa implements Runnable {
static int count = 0;
public static void main(String[] args) {
aaa aaa = new aaa();
aaa.create();
}
public void create() {
ExecutorService executor = Executors.newFixedThreadPool(100);
for (int i = 0; i < 1000; i++) {
aaa thread = new aaa();
executor.execute(thread);
}
executor.shutdown();
while (true){
if(executor.isTerminated()){
System.out.println("a " + count);
break;
}
}
}
#Override
public void run() {
this.test();
}
public void test() {
Lock lock = new ReentrantLock();
try {
lock.lock();
count++;
System.out.println(count);
} finally {
lock.unlock();
}
}
}
OR:
public synchronized void test() {
count++;
System.out.println(count);
}
the result is a random number sometimes 1000 sometimes 998, 999 ...etc and the print from inside the 'test' method is not in a sequence, it is like :
867
836
825
824
821
820
819
817
816
a 999
However, if it is in a synchronized block, everything looks good:
public void test() {
synchronized (aaa.class) {
count++;
System.out.println(count);
}
}
the result:
993
994
995
996
997
998
999
1000
a 1000
I think all of the methods above should give me the same result 1000, and the self increment should be in a sequence, but only the last method works.What is wrong with the code? Please help!!!
You are creating multiple instances of aaa, each instance creates its own ReentrantLock, and every thread in execution smoothly acquires a lock from its own instance.
public void test() {
Lock lock = new ReentrantLock();
try {
lock.lock();
count++;
System.out.println(count);
} finally {
lock.unlock();
}
}
Since there are multiple instances of aaa, each thread is running on its own instance and the synchronized method uses current object of aaa.class
public synchronized void test() {
count++;
System.out.println(count);
}
The reason for getting a proper result in this approach is, you are using the aaa.class as an object to the synchronization
public void test() {
synchronized (aaa.class) {
count++;
System.out.println(count);
}
}
The solution is, reuse the same lock(ReentrantLock) across all the threads. Defining the lock in the same level as the variable count would solve the issue.
You must create a single mutex, i.e.
static Lock lock = new ReentrantLock();
Your synchronized method does not work since you are creating N aaa instances then, every (non static) method is different (with their own mutex).
Your synchronized (aaa.class) works since aaa.class is the same Object for all aaa instances and methods.
Then, if you need synchronize the method be sure it is the same for all threads, e.g. if test is static will be the same for all
#Override
public void run() {
test();
}
public static synchronized void test() {
count++;
}
but you can inject a "counter class", e.g.
class Counter {
int count = 0;
// non static but synchronized for all (since they use the same `counter` object)
synchronized void inc() {
count++;
}
}
to be used for all threads
...
SyncTest thread = new SyncTest(counter); // <== the same
...
(full code)
public class SyncTest implements Runnable {
private final Counter c;
public SyncTest(Counter c) {
this.c = c;
}
static class Counter {
int count = 0;
// non static but synchronized for all (since they use the same `counter` object)
synchronized void inc() {
count++;
}
}
#Override
public void run() {
test();
}
public void test() {
this.c.inc();
}
public static void main(String[] args) {
// one counter for all
Counter counter = new Counter();
ExecutorService executor = Executors.newFixedThreadPool(100);
for (int i = 0; i < 10000; i++) {
SyncTest thread = new SyncTest(counter);
executor.execute(thread);
}
executor.shutdown();
while (true) {
if (executor.isTerminated()) {
System.out.println("a " + counter.count);
break;
}
}
}
}
Rule of thumb: Declare your lock variable on the next line after the variable(s) that you want to protect with it, and declare it with the same keywords. E.g.,
public class aaa implements Runnable {
static int count = 0;
static Lock countLock = new ReentrantLock();
...
If you read deeply enough into any of the other answers here, then you will see why this helps.

Thread can't read instances that are being modified by other threads

This scheme shows the functions that are being discussed below...
The OrderBook class looks like this:
public class OrderBook {
private TreeMap<Double, Double> bids;
private TreeMap<Double, Double> asks;
private Entry<Double, Double> bestBid;
private Entry<Double, Double> bestAsk;
public OrderBook() {
this.bids = new TreeMap<>();
this.asks = new TreeMap<>();
}
// Getters and setters...
// Example function that modifies its variables...
public void updateBids(double bidPrice, double bidVol) {
if(this.getBids().containsKey(bidPrice)) {
if(bidVol == 0.0) {
//System.out.println("Vol. 0: " + bidPrice + " - " + bidVol);
this.getBids().remove(bidPrice);
}
else if(bidVol > 0.0) {
//System.out.println("Actualizar Vol.: " + bidPrice + " - " + bidVol);
this.getBids().replace(bidPrice, bidVol);
}
else {
//System.out.println("Error. Unexpected volume:" +
// bidPrice + " - " + vol);
}
}
else {
// ...
}
this.setBestBid(this.getBids().lastEntry());
}
}
Client 1 class and Client 2 class are different from each other (they perform different write operations over the their OrderBook class) and they are launched from different threads. A Client class looks like this:
public class Client1 extends WebSocketClient {
private OrderBook ob;
public Client1(URI serverURI, OrderBook ob) {
super(serverURI);
this.ob = ob;
}
// Extended class implementations...
#Override
public void onMessage(String message) {
parse(message);
}
private void parse(String msg) {
JSONObject json = new JSONObject(msg);
if(json.has("b")) {
double b = json.getDouble("b");
double a = json.getDouble("a");
double B = json.getDouble("B");
double A = json.getDouble("A");
/**
* HERE performs the modification of the OrderBook class passed in the
* constructor. I don't know if this synchronized block is needed...
*/
synchronized(this.ob) {
this.ob.setBestBid(new AbstractMap.SimpleEntry<>(bidPrice, bidVol));
this.ob.setBestAsk(new AbstractMap.SimpleEntry<>(askPrice, askVol));
}
}
}
}
The problem comes when in the Main class (launched in another thread), I try to read the updated instances of the class OrderBook that are being modified by the Client x classes...
Main class looks like this...
public class Main implements Runnable {
private OrderBook ob1;
private OrderBook ob2;
public Oportunity(OrderBook ob1, OrderBook ob2) throws URISyntaxException {
this.ob1 = ob1;
this.ob2 = ob2;
}
#Override
public void run() {
while(true) {
// PROBLEM HERE: doesn't show anything...
System.out.println(this.ob1.getLasValue());
System.out.println(this.ob2.getLasValue());
}
}
public static void main(String[] args) throws Throwable {
OrderBook ob1 = new OrderBook();
OrderBook ob2 = new OrderBook();
Thread client1 = new Thread(new Client1(new URI("..."), ob1));
Thread client2 = new Thread(new Client2(new URI("..."), ob2));
Thread m = new Thread(new Main(ob1, ob2));
client1.start();
client2.start();
m.start();
}
}
QUESTIONS:
How could I access consistently the last updated values of both instances of OrderBook?
Also, is it possible to show priority on write operations over read operations?
Your resource should be protected by a Lock.
Your synchronized block is useless, you should protect OrderBook methods.
synchronized keyword is used to protect resources.
public class CriticalData {
private int sum = 0;
public void synchronized add() {
this.setSum(this.getSum() + 1);
}
// Synchronized Getters & setters
}
#Test
public void multiThreadedAddition() {
// GIVEN
ExecutorService service = Executors.newFixedThreadPool(3);
CriticalData data = new CriticalData();
// WHEN
IntStream.range(0, 1000)
.forEach(count -> service.submit(data::add));
service.awaitTermination(1000, TimeUnit.MILLISECONDS);
// THEN
assertEquals(1000, data.getSum());
}
Orderbook methods should be synchronized
public void synchronized updateBids(double bidPrice, double bidVol) {
// Edit critical data here
}
Warning: When constructing an object that will be shared between threads, be very careful that a reference to the object does not "leak" prematurely. For example, suppose you want to maintain a List called instances containing every instance of class. You might be tempted to add the following line to your constructor: instances.add(this);
But then other threads can use instances to access the object before construction of the object is complete.
Your OrderBook getter getLasValue is leaking

While loop and checking static variable

I have two threads and in one thread I set static variable and in another I check static variable via function like this
Test test= new Test();
while(!Temp.isVarSet()){
}
System.out.println("Variable set");
But this codes hangs - doesn't go to println statement. But the following code works
Test test= new Test();
while(!Temp.isVarSet()){
System.out.println("I am still here");
}
System.out.println("Variable set");
The Temp class
public class Temp {
private volatile static boolean varSet=false;
public synchronized static void setVarSet() {
Temp.varSet=true;
}
public synchronized static boolean isVarSet() {
return Temp.varSet;
}
}
Test class
public class Test{
public Test() {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Model model= new Model();
View view = new View();
Controller controller=new Controller(model, view);
Temp.setVarSet();
...
}
});
}
}
What can be reason? I set method isVarSet() synchronized but it didn't help.
EDIT
This code works too.
Test test = Test()
while(!Temp.isVarSet()){
Thread.sleep(100);
}
You didn't publish what happens in Temp and isVarSet but most probably you change a variable. This variable must be marked volatile.
If your class looks like this:
public class Temp {
private static boolean someFlag;
public static boolean isVarSet() {
return someFlag;
}
}
And your loop is the same as the example, the compiler thinks that there's no need to read the flag over and over again because the flag is not changed inside the loop and it optimizes to not read the flag over and over.
Marking someFlag as volatile:
private static volatile boolean someFlag;
Will force the runtime to check the flag on each iteration and not just assume that the value hasn't changed. In this case, it will work.
From Oracle docs about atomic access:
Atomic actions cannot be interleaved, so they can be used without fear
of thread interference. However, this does not eliminate all need to
synchronize atomic actions, because memory consistency errors are
still possible. Using volatile variables reduces the risk of memory
consistency errors, because any write to a volatile variable
establishes a happens-before relationship with subsequent reads of
that same variable. This means that changes to a volatile variable are
always visible to other threads. What's more, it also means that when
a thread reads a volatile variable, it sees not just the latest change
to the volatile, but also the side effects of the code that led up the
change.
Even after you made variable as volatile .
if you add SOP in while loop it is working
These two usecase gives me another thought. just try it.
Since your read and write methods are sync , in your while loop
while(!Temp.isVarSet()){
}
It is nothing doing other than calling the method, it may possible this sync method holds the lock on the Temp Object which does not allow other thread to modify the values (though sync setMethod) .
While add SOP inside the while , it is doing some work on IO and thus it is allowing some time slice to other thread get the lock of Temp and modify the same.
Could you please try remove Sync from read method , just for testing purpose and post your results.
public class Temp {
private volatile static boolean varSet=false;
public synchronized static void setVarSet() {
Temp.varSet=true;
}
public static boolean isVarSet() {
return Temp.varSet;
}
}
This works perfect for me:
public class ThreadTest {
public static void main(String[] args) throws Exception {
Thread t1 = new TheThread();
t1.start();
// wait
Thread.sleep(500);
System.out.println(Thread.currentThread().getId() + " will now setVarSet()");
Temp.setVarSet();
System.out.println(Thread.currentThread().getId() + " setVarSet() setted");
t1.join();
System.out.println(Thread.currentThread().getId() + " end programm");
}
private static class TheThread extends Thread {
#Override
public void run() {
System.out.println(Thread.currentThread().getId() + " enter run");
while (!Temp.isVarSet()) {
System.out.println(Thread.currentThread().getId() + " running");
try {
Thread.sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
// ignore
}
}
System.out.println(Thread.currentThread().getId() + " exit run");
}
}
private static class Temp {
private volatile static boolean varSet = false;
public static void setVarSet() {
Temp.varSet = true;
}
public static boolean isVarSet() {
return Temp.varSet;
}
}
}
Can you please post a complete example?
Its working as expected without hanging the program.
private volatile static boolean varSet = false;
public synchronized static void setVarSet() {
varSet = true;
}
public synchronized static boolean isVarSet() {
return varSet;
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
while (!TestDemo.isVarSet()) {
// System.out.println("I am still here");
}
System.out.println("Variable set");
}
});
t1.start();
Thread.sleep(1000); // put delay to give the chance to execute above thread
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// Model model= new Model();
// View view = new View();
// Controller controller=new Controller(model, view);
setVarSet();
}
});
}

Java method synchronization improper usage?

Suppose there is the following code:
class MyClass {
synchronized void myMethod1() {
//code
}
synchronized void myMethod2() {
//code
}
}
Now suppose myMethod1() and myMethod2() access distinct data; now if there are two threads, thread A calling only myMethod1() and thread B calling only myMethod2().
If thread A is executing myMethod1(), will thread B block waiting on myMethod2() even if they don't access the same data and there is no reason for this? As far as I know, synchronized methods use the monitor of this object for instance methods and that of MyClass.class object for static functions.
Your understanding of the situation is correct.
The typical solution is to have separate dedicated lock objects for the resources in question.
class MyClass {
private final Lock lock1 = new ReentrantLock();
private final Lock lock2 = new ReentrantLock();
void myMethod1() {
lock1.lock();
try {
//code
} finally {
lock1.unlock();
}
}
void myMethod2() {
lock2.lock();
try {
//code
} finally {
lock2.unlock();
}
}
}
You are correct in all your suppositions. In the case where no data is in common then there is no reason to synchronize at the method level.
The sychronized method will lock on the object itself. So each method will have to wait for the other to finish its access to release the object. If your methods are truly accessing distinct data you can do something like this:
class MyClass {
private static Object mLock1 = new Object();
private static Object mLock2 = new Object();
void myMethod1() {
synchronized(mLock1) {
//code
}
}
void myMethod2() {
synchronized(mLock2) {
//code
}
}
}
And you can then access them independently.
edit: You can essentially think of synchronized methods as being equivalent to this:
void myMethod1() {
synchronized(this) {
//your code
}
}
Shown like this it is pretty clear why two synchronized methods block each other because they have to wait for the lock on this to free.
Yes, declaring both methods as synchronized will make them block each other, even if they access different data elements.
To avoid this, you can use a more fine grained locks. E.g.:
class MyClass {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
void myMethod1() {
synchronized (lock1) {
//code
}
}
void myMethod2() {
synchronized (lock2) {
//code
}
}
You can use different monitors for myMethod1 and myMethod2 as follows:
class MyClass {
Object monitor1 = new Object();
Object monitor2 = new Object();
void myMethod1() {
synchornized(monitor1) {
//code
}
}
void myMethod2() {
synchronized(monitor2) {
//code
}
}
}

IlleagalMonitorStateException when I am trying to run this program

public class ThreadTest
{
public static Integer i = new Integer(0);
public static void main(String[] args) throws InterruptedException
{
ThreadTest threadTest = new ThreadTest();
Runnable odd = threadTest.new Numbers(1, "thread1");
Runnable even = threadTest.new Numbers(0, "thread2");
((Thread) odd).start();
((Thread) even).start();
}
class Numbers extends Thread
{
int reminder;
String threadName;
Numbers(int reminder, String threadName)
{
this.reminder = reminder;
this.threadName = threadName;
}
#Override
public void run()
{
while (i < 20)
{
synchronized (i)
{
if (i % 2 == reminder)
{
System.out.println(threadName + " : " + i);
i++;
i.notify();
}
else
{
try
{
i.wait();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
}
You can't synchronize on i because it changes during execution of your program.
Since Integer in Java is immutable, after executing i++ i will contain a reference to another object, not the object you have synchronized on. So, you can't call wait()/notify() on this new object, because these methods may be only called on the object you are synchronized on, otherwise you get IllegalMonitorStateException.
You need to synchronize on some other object that doesn't change during execution. For example, you may create a separate object for this purpose:
public class ThreadTest {
public static Integer i = new Integer(0);
public static Object lock = new Object();
...
class Numbers extends Thread {
...
#Override
public void run() {
...
synchronized (lock) {
...
lock.notify();
...
lock.wait();
...
}
}
}
}
This line:
i++;
is equivalent to:
i = i + 1;
which (due to autoboxing) becomes something like:
i = new Integer(i.intValue() + 1);
So, when you call i.notify() you are synchronized on the old i, not the new one.
I'd suggest changing i into an ordinary int variable, and create a separate object to synchronize on:
static int i = 0;
static Object iMonitor = new Object();
As documentation states the exception is thrown when
the current thread is not the owner of the object's monitor
It also states that
This method should only be called by a thread that is the owner of this object's monitor.
And this condition can be obtained by
By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes on the object.
For objects of type Class, by executing a synchronized static method of that class.
You could try calling the wait method from inside the class that uses i. This could be done by extending the class and writing two new methods for notify and wait..
You cannot put wait() and notify() in the same synchronized block because that will just cause a deadlock. Make sure only the wait and notify functions are wrapped with a synchronized block like this:
synchronized (i) {
i.wait(); // or i.notify();
}

Categories

Resources