I am trying to figure what would be the best way to fix this broken concurrency issue with this kind of code. I have tried adding a lock around "index++" but is there a better way of achieving concurrency?
public class MainClass {
public static short index = 0;
public static void main(String[] args) {
MainClass testConc = new MainClass();
Thread thr1 = new Thread(testConc.new MyRunnable());
thr1.start();
Thread thr2 = new Thread(testConc.new MyRunnable());
thr2.start();
}
class MyRunnable implements Runnable {
private static final Object lock = new Object();
public void run() {
while (index < 99) {
System.out.println(index);
synchronized(lock) {
index++;
}
}
}
}
}
You should have the lock at the same level (MainClass) as the data it is used for protecting. Class variable index should actually have private scope, because synchronization only happens in-class.
Also, as pointed out by Tomáš in the comment, the variable should be marked as volatile, which guarantees that any changes to the its value are visible to all threads (since Java 5). This removes the need to synchronize read access to index. So the corrected code looks something like:
public class MainClass {
private static volatile short index = 0;
private static final Object lock = new Object();
...
If you want the program to output the indices from 0 to 98 in order and only once per index value, you need to modify the run() method into this:
public void run() {
while (index < 99) {
synchronized (lock) {
// double-check for threads that made it here
// before #index got incremented to 99 by the thread that
// made the final increment
if (index < 99) {
System.out.println(index);
index++;
}
}
}
}
Notice that a double-check for index < 99 is required because index may have been changed by an another thread after the value was evaluated in the while condition. You'll see this if you increase the number of threads that are spawned by MainClass using the old version of run().
AtomicInteger would be better than locking around index++
It is designed especially for that use case.
Also by locking you are not achieving concurrency but thread safety/atomicity (if implemented properly).
By the way, I don't see the 'broken concurrency issue' in your code.
Related
In one of the interview, a coding question was asked to me and I had to find the problem in that code and suggest proper solution.
Please find below the entire code:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class Atomic {
static AtomicInteger count = new AtomicInteger(0);
static int counter = 0;
public static class Runnable extends Thread {
public void run() {
while (count.getAndSet(1) != 0) {
try {
Thread.sleep(3000);
} catch (Exception e) {
}
}
counter = counter + 1;
count.set(0);
}
}
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
Runnable runnable = new Runnable();
executor.execute(runnable);
}
executor.shutdown();
}
}
This code is running properly. But question is , there is some problem in this code if number of threads get increased or if I run For loop for almost 10000 times.
I tried to find the problem, but couldn't find one.
There are several things wrong with this code. You've not stated with "there is some problem" means, but here are the things that jump out.
Firstly, the counter variable is not updated safely. Multiple threads don't have guaranteed visibility of the last-written value; nor do you have the guarantee that no other thread has updated its value in between the read and the write.
The simple solution to this: change counter to an AtomicInteger, and use getAndIncrement or incrementAndGet to increment it.
Secondly, public static class Runnable extends Thread { is extremely dubious.
Don't hide the names of commonly-known Java classes (this is hiding java.lang.Runnable)
Don't extend Thread directly, especially when all you need is a java.lang.Runnable to add execute with an ExecutorService.
A more suitable class declaration would be:
public static class MyRunnable implements Runnable {
(or whatever you want to call it)
Or you can just declare an anonymous class:
executor.execute(new Runnable() { /* body */ });
Or you can just declare a lambda:
executor.execute(() -> { /* body */ });
Thirdly, count doesn't really seem to be serving an obvious purpose here. The logic of the runnable seems to be:
If "flag" is false:
Set "flag" to true
Increment a variable
Set "flag" to false
Otherwise:
Wait 3 seconds
Try again
count is playing the role of "flag" here. It's effectively just an AtomicBoolean.
But you don't need a separate count variable at all, if you make the counter an AtomicInteger:
while (true) {
int current = counter.get();
if (counter.compareAndSet(current, current + 1)) {
// Nothing else is trying to update "current" at the same time:
// we updated it. Stop.
break;
}
// Something else is trying to update at the same time.
// Sleep for 3 seconds.
Thread.sleep(3000);
}
Let us say I have two classes, A main class and a Thread class as follows:
public class A {
public static void main(String []args){
int count = 0;
for(int i = 0; i < 10; i++){
count+=10;
//here on every addition, I want to update the variable countOfAdd of the thread class
//and when countOfAdd value is in multiples of 5 I want to print a statement
}
}
class B extends Thread {
int countOfAdd;
#Override
public void run(){
//on value received
count+=1;
}
}
I don't know whether this is possible or not. If it is possible how to do it
Thanks in advance.
The normal way to do that is a queue.
Create a queue and make references to it available to both threads.
The main thread should add() an element to the queue (e.g. the amount of increment).
The other thread should poll() the queue and use this information to update its internal state.
This way none of the intermediate updates are going to be lost between the threads.
The quick and dirty way is direct access and locking.
Both of your threads can keep a reference to a common piece of data, and a common lock object (which can just be a Object commonLock = new Object()).
Every time either thread needs to access the data member, they do it holing a lock, e.g.:
synchronized (commonLock) { commonCount +=1; } // One thread.
synchronized (commonLock) { if (commonCount > 1) {...} } // Another thread.
This is harder to reason about, but can be made serviceable if the number of accesses in each thread is made small, preferably just one.
I don't know why you are using Thread here but anyway.
1. Without Thread
public class A {
public static void main(String []args){
int count = 0;
B objectB = new B();
for(int i = 0; i < 10; i++){
count+=10;
//here on every addition, I want to update the variable countOfAdd
//of the thread class and when countOfAdd value is in multiples of 5
//I want to print a statement
objectB.setCount(YourInput);// set your value
if(objectB.getValue()%5==0){
//do your task
}
}
}
class B {
int countOfAdd;
public int getCount(){return countOfAdd;}
public void setCount(int ){this.countOfAdd =countOfAdd;}
}
2. With Thread
Use Pub-sub pattern
Implementation of pub sub pattern in Java
I have an idea about multi-threading but I never worked on it. So, when I see my application at work... I haven't seen any class extending Thread creating a Thread. So, synchronized keyword is used when 2 objects try to access a variable at the same time.. we use synchronized to avoid conflicts.
Example:
public class Test {
private static int count = 0;
public static synchronized void incrementCount() {
count++;
}
}
If test class was using by an object then it makes sense to add synchronized to incrementcount(). But when you don't extend Thread or Runnable then what's the use of writing synchronized.
Synchronized isn't for threads or Runnables, it's used for data structures that are accessed by multiple threads in order to make sure each thread accesses them in a way that doesn't corrupt their data. Your own example is a rudimentary case of this, where count is incremented in a way that isn't threadsafe (using ++, see this question), so it needs locking to make sure only one thread at a time can increment it.
If there's other code that accesses count it also needs to be synchronized so that updates to count are visible to it. If all you're doing is incrementing a counter then it makes more sense to use a class like java.util.concurrent.atomic.AtomicInteger, and you can do without the synchronized keyword altogether.
For using synchronized to make sense it does assume there are multiple threads. Even if your own code doesn't create new threads, there can be cases where multiple threads are calling your code (such as in a servlet container, where the container manages a threadpool and allocates a thread to each incoming request).
A class does not need to extend Thread or implements Runnable to mark it's method as synchronized to protect from multiple thread access
Your class may a parameter to some other thread class and that thread class may have multiple instances. To provide strong consistency of data, you have protect your critical section of code & data.
Just change your code example as below.
I am demonstrating "synchronized" at object level rather than class level ( static synchronized)
class Test {
private int count = 0;
public void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
Test t = new Test();
for ( int i=0; i<10; i++){
new Thread(new MyRunnable(t)).start();
}
}
}
Your class Test has been passed as a parameter to thread MyRunnable. Now you have created multiple instances of threads. In absence of synchronized keyword, the output is unpredictable as follows.
java SynchronizedDemo
Count:2
Count:3
Count:2
Count:7
Count:6
Count:5
Count:4
Count:10
Count:9
Count:8
If I change
public void incrementCount() {
to
public synchronized void incrementCount() {
the output is:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10
On a different note, you have make your method as static synchronized. That means lock is maintained at class level instead of object level.
Have a look at oracle documentation page for better understanding.
Demo of code for absence of "static synchronized"
class Test {
private static int count = 0;
public static void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
for ( int i=0; i<10; i++){
Test t = new Test();
new Thread(new MyRunnable(t)).start();
}
}
}
output:
Count:5
Count:4
Count:3
Count:2
Count:10
Count:9
Count:8
Count:7
Count:6
After making
public static void incrementCount() {
to
ppublic static synchronized void incrementCount() {
output:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10
In this example, unlike earlier, we have created 10 different Test instances.
i++, even though it looks like a single instruction, is actually multiple instructions:
Set a temporary variable to 1+i.
Set the variable i to the temporary variable.
However, suppose the thread that executes i++ is interrupted after step 1, and the interrupting thread also calls i++. Then, this would happen:
(Suppose i=1)
Original thread: set temporary variable1 to 1+i, or 2.
Interrupting thread: set temporary variable2 to i+1, also 2
Interrupting thread: set i to temporary variable2. Now i=2
Original thread: set i to temporary variable1. Now i=2
The problem is that if i++ is called twice, it should be 3, not 2.
A synchronized void would put a lock on the variable i until the entire void completes executing. For example:
Original thread: set temporary variable1 to 1+i, or 2. Puts a lock on the variable i.
Interrupting thread: TRIES TO set temporary variable2 to i+1, but waits because of the lock on variable i
Original thread: set i to temporary variable1. Now i=2. The variable i is now unlocked.
Interrupting thread: "notices" that i has been unlocked, so it sets temporary variable2 to i+1 which is 3.
Interrupting thread: sets i to 3, which is expected behavior.
synchronized voids essentially lock variables temporarily to avoid confusing the program's execution.
As far as I know, volatile variables will be always read and written from the main memory. Then I think about the Singleton class. Here is how my program is:
1. Singleton class
public class Singleton {
private static Singleton sin;
private static volatile int count;
static{
sin = new Singleton();
count = 0;
}
private Singleton(){
}
public static Singleton getInstance(){
return sin;
}
public String test(){
count++;
return ("Counted increased!" + count);
}
}
2. Main class
public class Java {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Derived d1 = new Derived("d1");
d1.start();
Derived d2 = new Derived("d2");
d2.start();
Derived d3 = new Derived("d3");
d3.start();
}
;
}
class Derived extends Thread {
String name;
public Derived(String name){
this.name = name;
}
public void run() {
Singleton a = Singleton.getInstance();
for (int i = 0; i < 10; i++) {
System.out.println("Current thread: "+ name + a.test());
}
}
}
I know this maybe a dumb question, but i'm not good at multithreading in Java thus this problem confuses me a lot. I thought the static volatile int count variable in Singleton class will always have the latest value, but apparently it does not...
Can someone help me to understand this?
Thank you very much.
The problem is that volatile has nothing to do with thread synchronization. Even though the read from static volatile int count would indeed always return the latest value, multiple threads may write the same new value back into it.
Consider this scenario with two threads:
count is initialized zero
Thread A reads count, sees zero
Thread B reads count, sees zero
Thread A advances count to 1, stores 1
Thread B advances count to 1, stores 1
Thread A writes "Counted increased! 1"
Thread B writes "Counted increased! 1"
Both threads read the latest value, but since ++ is not an atomic operation, once the read is complete, each thread is on its own. Both threads independently compute the next value, and then store it back into the count variable. The net effect is that a variable is incremented once, even though both threads performed the increment.
If you would like to increment an int from multiple threads, use AtomicInteger.
As Jon Skeet indicated, it would be best if you use AtomicInteger. Using volatile variables reduces the risk of memory consistency errors, but it doesn't eliminate the need to synchronize atomic action.
I think this modification would help with your problem.
public synchronized String test(){
count++;
return ("Counted increased!" + count);
}
Reader threads are not doing any locking and until writer thread comes out of synchronized block, memory will not be synchronized and value of 'sin' will not be updated in main memory. both threads reads the same values and thus updates it by adding one, if you want to resolve make test method synchronised.
Read more: http://javarevisited.blogspot.com/2011/06/volatile-keyword-java-example-tutorial.html#ixzz3PGYRMtgE
I have a friend who said that all static methods should be synchronized in the context of a Java web application. Is that true? I have read many other stack overflow pages regarding this. What I have come to believe is that you only need to synchronize if you have:
Multiple Threads (As in a Sevlet Container with a thread pool)
Single ClassLoader
Shared data between threads, whether it is Session data or static member data.
Shared data must be mutable. Read only data is ok to share.
Based on this I think that static members should be synchronized, but not static methods.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadTest {
static String staticString = "";
// This static method is safe b/c it only uses local data.
// It does not use any shared mutable data.
// It even uses a string builder.
static String safeStaticMethod(String in) {
// This also proves that StringBuilder is safe
// When used locally by a thread.
StringBuilder sb = new StringBuilder();
sb.append("Hello: ");
sb.append(in);
return sb.toString();
}
// This static method is not safe b/c it updates and reads
// shared mutable data among threads.
// Adding synchronized will make this safe.
static String unsafeStaticMethod(String in) {
staticString = in;
StringBuffer sb = new StringBuffer();
sb.append("Hello: ");
sb.append(staticString);
return sb.toString();
}
public static void main(String[] args) {
ThreadTest test = new ThreadTest();
test.staticMethodWithLocalData();
test.staticMethodWithStaticData();
}
public void staticMethodWithLocalData() {
ExecutorService executor = Executors.newFixedThreadPool(2);
final int iterations = 100000;
executor.submit(new Runnable() {
#Override
public void run() {
for (int index = 0; index < iterations; ++index) {
if (!safeStaticMethod("Thread1").equals("Hello: Thread1")) {
System.out.println("safeStaticMethod at " + index);
}
}
}
});
executor.submit(new Runnable() {
#Override
public void run() {
for (int index = 0; index < iterations; ++index) {
if (!safeStaticMethod("Thread2").equals("Hello: Thread2")) {
System.out.println("safeStaticMethod at " + index);
}
}
}
});
}
public void staticMethodWithStaticData() {
ExecutorService executor = Executors.newFixedThreadPool(2);
final int iterations = 100000;
executor.submit(new Runnable() {
#Override
public void run() {
for (int index = 0; index < iterations; ++index) {
if (!unsafeStaticMethod("Thread1").equals("Hello: Thread1")) {
System.out.println("unsafeStaticMethod at " + index);
}
}
}
});
executor.submit(new Runnable() {
#Override
public void run() {
for (int index = 0; index < iterations; ++index) {
if (!unsafeStaticMethod("Thread2").equals("Hello: Thread2")) {
System.out.println("unsafeStaticMethod at " + index);
}
}
}
});
}
}
Does this code prove the point?
EDIT: This is only some throwaway code I hacked up to prove the point.
No, not all static methods need to be synchronized. Your list is basically complete as far as I can see. Be particularly careful when the static method either
accesses a static member that is mutable, or
gets passed a reference to an object that can be modified.
I think it goes without saying that 1 (having threads in the first place) is a precondition, since without threads synchronize makes no sense.
I've never heard 2, so I don't know for sure if it's a consideration.
No that's not true and I'm sure it would be detrimental. Not every application needs to be concurrent, and even in applications that do need to be concurrent, not every piece of code has to be.
As more evidence, look at the source of String. There are many static methods in there, but I could only find one synchronized method, and that one isn't even static.
Static methods should almost never be synchronized in a webapp. Unless you are 100% sure that the only people who will ever use the application are your 3 person accounting team, and willing to be red in the face if it takes off company-wide and all of the sudden grinds to a near halt.
Creating a global, blocking, shared resource is a total failure in scalability! It's also going to cause you lots of headaches and likely lock you into a Terracotta style solution if you end up needing to cluster the application server.
In a web application(like one build using the servlet/JSP), you should always avoid making a method as synchronized as it challenges the whole philosophy of mutli-thread accessibility. In place, always try to place the only necessary code, which needs to be accessed one by one, inside the synchronized block.
Not at all. Mostly, the static methods that I have come across do not modify any static variables and hence they do not require to be synchronized.
For simple understanding,
//sample static util method to get string in upper case
public static String getName(String name){
return a.toUpperCase();
}
The above method can be called by 1000s of threads and yet it is going to be thread-safe because the method only requires an argument- String name and that is from the Thread Stack. It is not shared data between threads.
Think about it, if all the static methods were synchonized, the web-applications shall be extremely slow and lethargic to use. We shall have class-level lock whenever a single thread tries to access the method.
There are a lot of static methods in the APIs provided by JDK. If all those were synchronized, am pretty sure we wouldn't be using JAVA.
In your case, there is a static variable(class level variable) that is being modified by the static method. Yes, if multiple threads are created and they are going to access the static method, there is a possibility of Thread Interference. It is not thread-safe as there is shared data between them.
Mostly, the static methods are utility functions depending on the arguments being passed to them.
Please note that non-synchronized static methods are thread safe if they don't modify static class variables.