Is it possible to update an attribut within a thread - java

Let say that I create an object and run it in a thread, something like this.
public class Main {
public static void main(String[] args) {
SomeClass p = new SomeClass (143);
p.start();
p.updateNumber(144);
}}
Is it possible to update the parameter passed in SomeClass with a methode updateNumber() as fallows:
# Updated
class SomeClass extends Thread {
volatile int number ;
SomeClass (int number ) {
this.number = number ;
}
public void run() {
while(true){
System.out.println(number);
}
}
public void updateNumber(int n){
number =n;
}
}
Result :
144
144
144
144
144
...
Thanks

Yes, but you need to declare number as volatile, or (preferably) use an AtomicLong instead of a long.

Declare number as volatile.
When is volatile needed ?
When multiple threads using the same
variable, each thread will have its
own copy of the local cache for that
variable. So, when it's updating the
value, it is actually updated in the
local cache not in the main variable
memory. The other thread which is
using the same variable doesn't know
anything about the values changed by
the another thread. To avoid this
problem, if you declare a variable as
volatile, then it will not be stored
in the local cache. Whenever thread
are updating the values, it is updated
to the main memory. So, other threads
can access the updated value

One other option not mentioned and which is the option you should use instead of synchronization as mentioned above is the make use of the Concurrency package introduced by Doug Lee in Java 1.5.
Use the Atomic classes, these take care of all you concurrency woes. (well to a point)
Something like this:
private AtomicInteger number = new AtomicInteger(0);
public void updateNumber(int n) {
number.getAndSet(n);
}
public int getNumber() {
return number.get();
}
Java 1.6 AtomicInteger JavaDoc
Java Concurrency in Practice
In my opinion the Java Concurrency in Practice is the best book on threading in Java

SomeClass even it is Runnable, it is just a normal class and objects of it can be accessed by any thread that has reference to it. In your example. you are not calling updateNumber() form anywhere, but if you call it after p.start(), you are acessing it from the thread that actually made the instance. If you are calling updateNumber() in run(), then you are accessing it from the thread you've just started.
The other question is: is it safe in your setup to change it form multiple threads? the answer is no. You have to declare it as volatile (let say), or synchronize if you changing it based on current value. How and what to synchronize depends on what you are actually doing with it.

You can use the keyword volatilewhen all the following criteria are met:
Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value
The variable does not participate in invariants with other state variables
Locking is not required for any other reason while the variable is being accessed
Otherwise, I'd recommend using some sort of synchronization policy
class SomeClass implements Runnable {
private Integer number;
SomeClass (int number) {
this.number = Integer.valueOf(number);
}
#Override
public void run() {
while(true){
System.out.println(getNumber());
}
}
public void updateNumber(int n){
synchronized(number){
number = Integer.valueOf(n);
}
}
public int getNumber(){
synchronized(number){
return number.intValue();
}
}
}

Yes, you can just call p.updateNumber(...) but you will need to be careful of thread synchronization issues.

Related

Should I synchronize method in my example?

I'm not sure if I should synchronize method methodOne() in my example. I think not but I'm not 100% sure. Could you please give me advice what to do?
public class SynchroIssue {
class Test {
private double a = 0;
void methodOne() {
a++;
}
void go() {
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
methodOne();
System.out.println(Thread.currentThread().getName() + ", a = " + a);
}
}
}).start();
}
}
public static void main(String... args) {
SynchroIssue mainObj = new SynchroIssue();
SynchroIssue.Test object1 = mainObj.new Test();
SynchroIssue.Test object2 = mainObj.new Test();
object1.go();
object2.go();
}
}
Assuming that you are actually going to use instances of the SynchroIssue class concurrently, which you are not doing currently, the answer is yes.
The increment operator is not atomic. It is actually 3 instructions:
Get the current value.
Add 1 to that.
Store new value.
If you are not synchronized, concurrent threads can overlap those steps resulting in strange behavior.
Another option, if you are truly only interested in integers, would be the use of AtomicInteger, which has methods to atomically increment.
object1 and object2 are different objects, each start only one thread, and the variable "a" is private and not static, so "a" are different objects too, and there is no interaction between threads. So there is no need to synchronise methodOne().
In this specific example there's no value to be gained by synchronising the methods because only a single thread ever actually interacts with a given instance.
If you called object1.go() twice you'd have a problem. Using synchronized would not be the best solution to that problem though, you should instead use a java.util.concurrent.atomic.DoubleAccumulator, although AtomicInteger would function just as well given that you start at 0 and only ever increment by 1.
In general, you should be wary of using synchronized to roll your own synchronisation protocols. Prefer instead known thread-safe classes where they're available. java.util.concurrent is a good place to look.
You should, but it wouldn't solve your problem.
If you would synchronize the method, only one thread would be able to increase the variable at a time. But the following System.out.println could still print another value, since by the time you call it, another thread may already have increased a.
The solution for your problem would be, that methodOne would also have to return the variable. Something like this:
synchronized double methodOne() {
return ++a;
}
And the thread should do:
for (int i = 0; i < Integer.MAX_VALUE; i++) {
System.out.println(Thread.currentThread().getName() + ", a = " + methodOne());
}
EDIT: as others already pointed out, you only have to do this if you intend to make the variable static. Otherwise you can leave your code as it is.
I want to add some hints to Brett Okken's answer:
Most of the times, when you have a member variable in your class which is modified by the methods of your class in a concurrent context by more than one thread, you should think about one of the synchronization scopes.
Always go for the smallest available scope of synchronization.
Hope this would be helpful.

Regarding volatile variable usage

I am new to the volatile variable but I was going through article which states 2) Volatile variable can be used as an alternative way of achieving synchronization in Java in some cases, like Visibility. with volatile variable its guaranteed that all reader thread will see updated value of volatile variable once write operation completed, without volatile keyword different reader thread may see different values.
I request you guys could you please show this with me a small java program , so technically also it is clear to me.
what I come from my understanding is...
Volatile means each Thread Access the variable will have its own private copy which is same as original one.But if the Thread is going to change that private copy,then original one will not get reflected.
public class Test1 {
volatile int i=0,j=0;
public void add1()
{
i++;
j++;
}
public void printing(){
System.out.println("i=="+i+ "j=="+j);
}
public static void main(String[] args) {
Test1 t1=new Test1();
Test1 t2=new Test1();
t1.add1();//for t1 ,i=1,j=1
t2.printing();//for t2 value of i and j is still,i=0,j=0
t1.printing();//prints the value of i and j for t1,i.e i=1,j=1
t2.add1();////for t2 value of i and j is changed to i=1;j=1
t2.printing();//prints the value of i and j for t2i=1;j=1
}
}
I request you guys could you please show a small program of volatile functionality, so technically also it is clear to me
Volatile variable as you have read guarantees visibility but doesn't guarantee atomicity - another important aspect of thread safety. I will try to explain by an example
public class Counter {
private volatile int counter;
public int increment() {
System.out.println("Counter:"+counter); // reading always gives the correct value
return counter++; // atomicity isn't guaranteed, this will eventually lead to skew/error in the expected value of counter.
}
public int decrement() {
System.out.println("Counter:"+counter);
return counter++;
}
}
In the example, you can see that the read operation will always give the correct value of counter at an instant of time, however atomic operations (like evaluate a condition and do something and read and write on the basis of read value) thread safety is not guaranteed.
You can refer this answer for additional details.
Volatile means each Thread Access the variable will have its own
private copy which is same as original one.But if the Thread is going
to change that private copy,then original one will not get reflected.
I am not sure I understand you correctly, but volatile fields imply they are read and written from the main memory accessible to all threads - there are no thread specific copies (caching) of the variable.
From JLS,
A field may be declared volatile, in which case the Java Memory Model
ensures that all threads see a consistent value for the variable

Using ThreadLocal in tandem with Volatile gives unpredictable results

I was reading through Java Memory model and was playing with volatile. I wanted to check how Volatile will work in tandem with ThreadLocal. As per definition ThreadLocal has its own, independently initialized copy of the variable whereas when you use volatile keyword then JVM guarantees that all writes and subsequent reads are done directly from the memory. Based on the high level definitions i knew what i was trying to do will give unpredictable results. But just out of curiosity wanted to ask if someone can explain in more details as if what is going on in the background. Here is my code for your reference...
public class MyMainClass {
public static void main(String[] args) throws InterruptedException {
ThreadLocal<MyClass> local = new ThreadLocal<>();
local.set(new MyClass());
for(int i=0;i<5; i++){
Thread thread = new Thread(local.get());
thread.start();
}
}
}
public class MyClass implements Runnable {
private volatile boolean flag = false;
public void printNameTillFlagIsSet(){
if(!flag)
System.out.println("Flag is on for : " + Thread.currentThread().getName());
else
System.out.println("Flag is off for : " + Thread.currentThread().getName());
}
#Override
public void run() {
printNameTillFlagIsSet();
this.flag = true;
}
}
In your code you create a ThreadLocal reference as a local variable of your main method. You then store an instance of MyClass in it and then give that same reference of MyClass to 5 threads created in the main method.
The resulting output of the program is unpredictable since the threads are not synchronized against each other. At least one thread will see the flag as false the other four could see the flag as either true or false depending on how the thread execution is scheduled by the OS. It is possible that all 5 threads could see the flag as false, or 1 could see it false and 4 see it true or anything in between.
The use of a ThreadLocal has no impact on this run at all based on the way you are using it.
As most have pointed out you have deeply misunderstood ThreadLocal. This is how I would write it to be more accurate.
public class MyMainClass {
private static final ThreadLocal<MyClass> local = new ThreadLocal<>(){
public MyClass initialValue(){
return new MyClass();
}
}
public static void main(String[] args) throws InterruptedException {
local.set(new MyClass());
for(int i=0;i<5; i++){
Thread thread = new Thread(new Runnable(){
public void run(){
local.get().printNameTillFlagIsSet();
local.get().run();
local.get().printNameTillFlagIsSet();
}
});
thread.start();
}
}
}
So here five different instances of MyClass are created. Each thread will have their own accessible copy of each MyClass. That is Thread created at i = 0 will always have a different instance of MyClass then i = 1,2,3,4 despite how many local.get() are done.
The inner workings are a bit complicated but it can be done similar to
ConcurrentMap<Long,Thread> threadLocalMap =...;
public MyClass get(){
long id = Thread.currentThread().getId();
MyClass value = threadLocalMap.get(id);
if(value == null){
value = initialValue();
threadLocalMap.put(id,value);
}
return value;
}
To further answer your question about the volatile field. It is in essence useless here. Since the field itself is 'thread-local' there will be no ordering/memory issues that can occur.
Just don't divinize the JVM. ThreadLocal is a regular class. Inside it uses a map from current thread ID into an object instance. So that the same ThreadLocal variable could have its own value for each thread. That's all. Your variable exists only in the main thread, so it doesn't make any sence.
The volatile is something about java code optimization, It just stops all possible optimizations which allow avoid redundant memory reads/writes and execution sequence re-orderings. It is important for expecting some particular behaviour in multi-threaded environment.
You have two big problems:
1) As many pointed out, you are not using ThreadLocal properly so you don't actually have any "thread local" variables.
2) Your code is equivalent to:
MyClass someInstance = new Class();
for (...)
... new Thread(someInstance);
so you should expect to see 1 on and 4 off. However your code is badly synchronized, so you get random results. The problem is that although you declare flag as volatile, this is not enough for good synchronization since you do the check on flag in printNameTillFlagSet and then change the flag value just after that method call in run. There is a gap here where many threads can see the flag as true. You should check the flag value and change it within a synchronized block.
You main thread where you have a ThreadLocal object is being passed to all the threads. So the same instance is being passed.
So its as good as
new Thread(new MyClass());
What you could try is have an object being called by different threads with a thread local variable. This will be a proper test for ThreadLocal where each thread will get its own instance of the variable.

Synchronization of non-final field

A warning is showing every time I synchronize on a non-final class field. Here is the code:
public class X
{
private Object o;
public void setO(Object o)
{
this.o = o;
}
public void x()
{
synchronized (o) // synchronization on a non-final field
{
}
}
}
so I changed the coding in the following way:
public class X
{
private final Object o;
public X()
{
o = new Object();
}
public void x()
{
synchronized (o)
{
}
}
}
I am not sure the above code is the proper way to synchronize on a non-final class field. How can I synchronize a non final field?
First of all, I encourage you to really try hard to deal with concurrency issues on a higher level of abstraction, i.e. solving it using classes from java.util.concurrent such as ExecutorServices, Callables, Futures etc.
That being said, there's nothing wrong with synchronizing on a non-final field per se. You just need to keep in mind that if the object reference changes, the same section of code may be run in parallel. I.e., if one thread runs the code in the synchronized block and someone calls setO(...), another thread can run the same synchronized block on the same instance concurrently.
Synchronize on the object which you need exclusive access to (or, better yet, an object dedicated to guarding it).
It's really not a good idea - because your synchronized blocks are no longer really synchronized in a consistent way.
Assuming the synchronized blocks are meant to be ensuring that only one thread accesses some shared data at a time, consider:
Thread 1 enters the synchronized block. Yay - it has exclusive access to the shared data...
Thread 2 calls setO()
Thread 3 (or still 2...) enters the synchronized block. Eek! It think it has exclusive access to the shared data, but thread 1 is still furtling with it...
Why would you want this to happen? Maybe there are some very specialized situations where it makes sense... but you'd have to present me with a specific use case (along with ways of mitigating the sort of scenario I've given above) before I'd be happy with it.
I agree with one of John's comment: You must always use a final lock dummy while accessing a non-final variable to prevent inconsistencies in case of the variable's reference changes. So in any cases and as a first rule of thumb:
Rule#1: If a field is non-final, always use a (private) final lock dummy.
Reason #1: You hold the lock and change the variable's reference by yourself. Another thread waiting outside the synchronized lock will be able to enter the guarded block.
Reason #2: You hold the lock and another thread changes the variable's reference. The result is the same: Another thread can enter the guarded block.
But when using a final lock dummy, there is another problem: You might get wrong data, because your non-final object will only be synchronized with RAM when calling synchronize(object). So, as a second rule of thumb:
Rule#2: When locking a non-final object you always need to do both: Using a final lock dummy and the lock of the non-final object for the sake of RAM synchronisation. (The only alternative will be declaring all fields of the object as volatile!)
These locks are also called "nested locks". Note that you must call them always in the same order, otherwise you will get a dead lock:
public class X {
private final LOCK;
private Object o;
public void setO(Object o){
this.o = o;
}
public void x() {
synchronized (LOCK) {
synchronized(o){
//do something with o...
}
}
}
}
As you can see I write the two locks directly on the same line, because they always belong together. Like this, you could even do 10 nesting locks:
synchronized (LOCK1) {
synchronized (LOCK2) {
synchronized (LOCK3) {
synchronized (LOCK4) {
//entering the locked space
}
}
}
}
Note that this code won't break if you just acquire an inner lock like synchronized (LOCK3) by another threads. But it will break if you call in another thread something like this:
synchronized (LOCK4) {
synchronized (LOCK1) { //dead lock!
synchronized (LOCK3) {
synchronized (LOCK2) {
//will never enter here...
}
}
}
}
There is only one workaround around such nested locks while handling non-final fields:
Rule #2 - Alternative: Declare all fields of the object as volatile. (I won't talk here about the disadvantages of doing this, e.g. preventing any storage in x-level caches even for reads, aso.)
So therefore aioobe is quite right: Just use java.util.concurrent. Or begin to understand everything about synchronisation and do it by yourself with nested locks. ;)
For more details why synchronisation on non-final fields breaks, have a look into my test case: https://stackoverflow.com/a/21460055/2012947
And for more details why you need synchronized at all due to RAM and caches have a look here: https://stackoverflow.com/a/21409975/2012947
I'm not really seeing the correct answer here, that is, It's perfectly alright to do it.
I'm not even sure why it's a warning, there is nothing wrong with it. The JVM makes sure that you get some valid object back (or null) when you read a value, and you can synchronize on any object.
If you plan on actually changing the lock while it's in use (as opposed to e.g. changing it from an init method, before you start using it), you have to make the variable that you plan to change volatile. Then all you need to do is to synchronize on both the old and the new object, and you can safely change the value
public volatile Object lock;
...
synchronized (lock) {
synchronized (newObject) {
lock = newObject;
}
}
There. It's not complicated, writing code with locks (mutexes) is actally quite easy. Writing code without them (lock free code) is what's hard.
EDIT: So this solution (as suggested by Jon Skeet) might have an issue with atomicity of implementation of "synchronized(object){}" while object reference is changing. I asked separately and according to Mr. erickson it is not thread safe - see: Is entering synchronized block atomic?. So take it as example how to NOT do it - with links why ;)
See the code how it would work if synchronised() would be atomic:
public class Main {
static class Config{
char a='0';
char b='0';
public void log(){
synchronized(this){
System.out.println(""+a+","+b);
}
}
}
static Config cfg = new Config();
static class Doer extends Thread {
char id;
Doer(char id) {
this.id = id;
}
public void mySleep(long ms){
try{Thread.sleep(ms);}catch(Exception ex){ex.printStackTrace();}
}
public void run() {
System.out.println("Doer "+id+" beg");
if(id == 'X'){
synchronized (cfg){
cfg.a=id;
mySleep(1000);
// do not forget to put synchronize(cfg) over setting new cfg - otherwise following will happend
// here it would be modifying different cfg (cos Y will change it).
// Another problem would be that new cfg would be in parallel modified by Z cos synchronized is applied on new object
cfg.b=id;
}
}
if(id == 'Y'){
mySleep(333);
synchronized(cfg) // comment this and you will see inconsistency in log - if you keep it I think all is ok
{
cfg = new Config(); // introduce new configuration
// be aware - don't expect here to be synchronized on new cfg!
// Z might already get a lock
}
}
if(id == 'Z'){
mySleep(666);
synchronized (cfg){
cfg.a=id;
mySleep(100);
cfg.b=id;
}
}
System.out.println("Doer "+id+" end");
cfg.log();
}
}
public static void main(String[] args) throws InterruptedException {
Doer X = new Doer('X');
Doer Y = new Doer('Y');
Doer Z = new Doer('Z');
X.start();
Y.start();
Z.start();
}
}
AtomicReference suits for your requirement.
From java documentation about atomic package:
A small toolkit of classes that support lock-free thread-safe programming on single variables. In essence, the classes in this package extend the notion of volatile values, fields, and array elements to those that also provide an atomic conditional update operation of the form:
boolean compareAndSet(expectedValue, updateValue);
Sample code:
String initialReference = "value 1";
AtomicReference<String> someRef =
new AtomicReference<String>(initialReference);
String newReference = "value 2";
boolean exchanged = someRef.compareAndSet(initialReference, newReference);
System.out.println("exchanged: " + exchanged);
In above example, you replace String with your own Object
Related SE question:
When to use AtomicReference in Java?
If o never changes for the lifetime of an instance of X, the second version is better style irrespective of whether synchronization is involved.
Now, whether there's anything wrong with the first version is impossible to answer without knowing what else is going on in that class. I would tend to agree with the compiler that it does look error-prone (I won't repeat what the others have said).
Just adding my two cents: I had this warning when I used component that is instantiated through designer, so it's field cannot really be final, because constructor cannot takes parameters. In other words, I had quasi-final field without the final keyword.
I think that's why it is just warning: you are probably doing something wrong, but it might be right as well.

What is the difference between synchronized and static synchronized?

For a travel booking web application, where there are 100 concurrent users logged in,
should ticket booking and generating an "E-Ticket Number" be implemented by a "synchronized" or a "static synchronized" method?
Well, are you aware of the difference between a static method and an instance method in general?
The only difference that synchronized makes is that before the VM starts running that method, it has to acquire a monitor. For an instance method, the lock acquired is the one associated with the object you're calling the method on. For a static method, the lock acquired is associated with the type itself - so no other threads will be able to call any other synchronized static methods at the same time.
In other words, this:
class Test
{
static synchronized void Foo() { ... }
synchronized void Bar() { ... }
}
is roughly equivalent to:
class Test
{
static void Foo()
{
synchronized(Test.class)
{
...
}
}
void Bar()
{
synchronized(this)
{
...
}
}
}
Generally I tend not to use synchronized methods at all - I prefer to explicitly synchronize on a private lock reference:
private final Object lock = new Object();
...
void Bar()
{
synchronized(lock)
{
...
}
}
You haven't provided nearly enough information to determine whether your method should be a static or instance method, or whether it should be synchronized at all. Multithreading is a complex issue - I strongly suggest that you read up on it (through books, tutorials etc).
Jon's answer covers the difference hinted at in your question title.
However, I would say that neither should be used for generating a ticket number. On the assumption that these are being stored in a database, somewhere - the database should be responsible for generating the number when you insert the new record (presumably by an autoincrementing primary key, or something similar).
Failing that, if you must generate the number within Java code, I suspect that the synchronisation overhead might be quite noticeable with 100 concurrent users. If you are running on Java 1.5 or later, I'd use a java.util.concurrent.AtomicInteger to get the ticket number, which you can simply call as
private static final AtomicInteger ticketSequence;
static
{
final int greatestTicket = getHighestExistingTicketNumber(); // May not be needed if you can start from zero each time
ticketSequence = new AtomicInteger(greatestTicket + 1);
}
public /*static*/ int getNextTicketNumber()
{
return ticketSequence.incrementAndGet();
}
This gives you the concurrent global uniqueness you need in a much more efficient fashion than synchronizing every time you need an integer.

Categories

Resources