Why is this class threadsafe? - java

Had there been a
public synchronized void deletePerson(Person p)
{ mySet.remove();}
then too it would remain threadsafe?

This class is threadsafe because there is only one mutable field in it (mySet) , it is private and all accesses to it are synchronized.
Yes, public synchronized void deletePerson(Person p) { mySet.delete();} would still keep this class thread-safe.
Also, note that the reference to mySet is not escaping from this class. Which is also important.

Since mySet is private and not exposed outside the class through a getMySet method, you can access to the state of the object only with the methods addPerson, containsPerson and deletePerson.
Since these 3 methods are synchronized, only one of them can access to the instance of the class (and change its state) at any given time, so the class is Thread Safe.

Related

How to make a class with static members and function thread safe?

I have a class defined as:
class Artifacts {
private static boolean isThreadStarted = false;
private SomeClass someClass;
public static void startThread() {
isThreadStarted = true;
}
public static void setSomeClass(SomeClass = someClass1) {
if(isThreadStarted) {
someClass = someClass1;
}
}
public static SomeClass getSomeClass() {
return someClass;
}
}
Now the use case is that a method will make the value of isThreadStarted to be true. After that, a thread will start and using the value of someClass.There can be multiple threads setting and getting the value of someClass. I want to make this thread safe.
There is an annotation #ThreadSafe and there is a function synchronized static which I guess will do the thing. Please help in deciding the right approach.
Two simple improvements you can make to make this class more threadsafe for the intended purpose are to make the someClass field volatile, and to use AtomicBoolean for the isThreadStarted field.
class Artifacts {
private static AtomicBoolean isThreadStarted = new AtomicBoolean(false);
private volatile SomeClass someClass;
The volatile will ensure that any other thread that has a reference to an Artifact instance, does not cache the someClass instance. The JVM will always retrieve the someClass field from one main source. If volatile is not used, then other threads may cache someClass and changes it it may not be reflected across all the threads that are using it.
AtomicBoolean gives you volatile feature plus atomic operations, like check and set in the same operation. Here is a excerpt from the Javadoc.
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:
So, your main concern is that multiple threads will read and write the someClass field (and maybe the isThreadStarted field, as well).
I don't know what the #ThreadSafe annotation does, it's not part of Java Standard Edition 8.
The basic way to make that thread-safe is to use the synchronized keyword. Typically, you'd encapsulate access to your field in getter and setter methods and make them synchronized.
public class Test {
private String someText;
public synchronized String getSomeText() {
return someText;
}
public synchronized void setSomeText(String someText) {
this.someText = someText;
}
}
But typically the multi-thread problems aren't tied to a single field.
If different threads of your program use a (thread-shared) object, you run into the risk that one thread modifies two fields A and B (e.g. moves money from A to B by subtracting from A and adding to B), and in-between some other thread reads A and B (e.g. calculates the current amount of A plus B) and sees an inconsistent state (amount subtracted from A, but not yet added to B).
The classical solution is to ensure that of all these code sections where the instance is read or modified, only one at a time is allowed to run. And that's what synchronized does.
Life_Hacker,
1st way
use static synchronized keyword with function to make Class Level lock in multithreading environment.
example :
public static synchronized void setSomeClass(Artifacts.class) {
if(isThreadStarted) {
someClass = someClass1;
}
}
2nd way
inside function definition, you can create Synchronize Block
example:
public static void setSomeClass(SomeClass = someClass1) {
synchronized(this){
if(isThreadStarted) {
someClass = someClass1;
}
}
}
2nd way is best approach

Instanciating a thread-safe class from a non thread-safe class

In a not thread-safe class you must avoid to use class variables at they can be shared by different threads end executing contexts.
But if you instanciate an external class which itself has class variables, will these be thread-safe ?
In this example, is there any risk to share the counter variable between threads ?
class MyNotThreadSafeClass()
{
private integer sharedvariable;
public void callAnOtherClass()
{
myClass o = new myClass();
System.out.println(o.increment(counter));
}
}
class myClass()
{
private integer counter;
public void increment() { return(counter++); }
}
Thank you if you have an idea (documentation is not very clear in this thread-safe topic).
This works since you never pass o to another thread. So no other thread can ever access this instance.
The general pattern is: If you share one instance between several threads, then you need to have some sort of synchronization.
If you don't share an instance, it doesn't matter if there are more threads.

Class Level and Object Level lock synchronization

class MyClass
{
public synchronized void print() {}
public static synchronized void buffer() {}
}
Making static object synchronized makes a CLASS level object where only one Thread can access this. The class has both static and non-static Synchronized methods.
Can other threads(Thread-B) access non-static synchronize methods() via object lock while another Thread (Thread-A) using static synchronized (Acquiring a class level lock) method?
I hope non of the threads access any of the static synchronized methods until (Thread-B) release the lock.
The answers to both your questions are "yes": static-level locks do not block instance-level synchronized methods, and they apply to all static synchronized methods.
Generally, though, synchronizing on the class is discouraged, because it leaves your class exposed to an infinite wait attack. The perpetrator synchronizes on the class, preventing all your static synchronized methods from running. A better approach is to make a private object for locking, and synchronize on it, like this:
class MyClass
{
public synchronized void print() {}
private static Object staticLock = new Object();
public static void buffer() {
synchronized(staticLock) {
...
}
}
}
Same goes for synchronizing the instance methods: if the class is to be used in potentially non-cooperative environment, you are better off with a private object for locking.
In short:
non-static methods use the current object's lock (only one thread per object)
static methods use the associated Class object (there is one per class, so, only one therad per Class object)
It's important to take into account erasure:
// If you have this:
class MyClass<T> {
static synchronized myMethod() { ... }
}
MyClass<Integer> objInt = new MyClass<Integer>();
MyClass<String> objString = new MyClass<String>();
// Then only one thread will be able to execute myMethod(),
// even when ojbInt and ObjString are not "exactly" the "same"
// class in compilation time
static locks
synchronized(YourClass.class/class object)
instance locks
synchronized(this/instance object)
both are not mutually exclusive, both thread will run concurrently

Concurrency in Java: synchronized static methods

I want to understand how locking is done on static methods in Java.
let's say I have the following class:
class Foo {
private static int bar = 0;
public static synchronized void inc() { bar++; }
public synchronized int get() { return bar; }
It's my understanding that when I call f.get(), the thread acquires the lock on the object f and when I do Foo.inc() the thread acquires the lock on the class Foo.
My question is how are the two calls synchronized in respect to each other?
Is calling a static method also acquires a lock on all instantiations, or the other way around (which seems more reasonable)?
EDIT:
My question isn't exactly how static synchronized works, but how does static and non-static methods are synchronized with each other.
i.e., I don't want two threads to simultaneously call both f.get() and Foo.inc(), but these methods acquire different locks. My question is how is this preventable and is it prevented in the above code.
Static and instance synchronized methods are not related to each other, therefore you need to apply some additional synchronization between them, like this:
class Foo {
private static int bar = 0;
public static synchronized void inc() { bar++; }
public synchronized int get() {
synchronized (Foo.class) { // Synchronizes with static synchronized methods
return bar;
}
}
}
(though in this case leaving synchronized on get() doesn't make sense, since it doesn't do anything that requires synchronization on instance).
Beware of deadlocks - since this code aquires multiple locks, it should do it in consistent order, i.e. other synchronized static methods shouldn't try to acquire instance locks.
Also note that this particular task can be solved without synchronization at all, using atomic fields:
class Foo {
private static AtomicInteger bar = new AtomicInteger(0);
public static void inc() { bar.getAndIncrement(); }
public int get() { return bar.get(); }
}
A synchronized static method is effectively equivalent to:
public static void foo() {
synchronized (ClassName.class) {
// Body
}
}
In other words, it locks on the Class object associated with the class declaring the method.
From section 8.4.3.6 of the JLS:
A synchronized method acquires a monitor (ยง17.1) before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (the object for which the method was invoked) is used.
If you read http://download.oracle.com/javase/tutorial/essential/concurrency/locksync.html.
It will tell you:
You might wonder what happens when a
static synchronized method is invoked,
since a static method is associated
with a class, not an object. In this
case, the thread acquires the
intrinsic lock for the Class object
associated with the class. Thus access
to class's static fields is controlled
by a lock that's distinct from the
lock for any instance of the class.
which tells you all you need to know.
Neither, the non-static synchronized call does not acquire a lock on the class itself. (And the static synchronized block does not lock any object instantiated from that class.)
In other words the calls f.get() (locks f) and Foo.inc() (locks the class Foo) can run concurrently. They are not "synchronized".
You could use a different pattern (singleton), or make all the methods static.
Static locks are attached to the class definition and thus is shared between all instances of that class.
Synchronization of none static methods only apply to the current instance of the class (the lock is on the class instance, e.g., this). In your example you have two different locks with no interrelation.
I don't want two threads to simultaneously call both f.get() and Foo.inc(), but these methods acquire different locks. My question is how is this preventable and is it prevented in the above code
You must share a lock to be able to arbitrate access to both f.get and Foo.inc(). You can do this either by sharing the same static lock or by the same instance lock.
These two calls do not synchronize in respect to each other.
It is as you said, a caller of f.get() acquires the lock of f object and caller of Foo.inc() acquires Foo.class object's one. So the synchronization rules are the same as if instead of static call you called an instance synchronized method with another object.

How to lock a method for a whole class using synchronized?

I know when you want to lock method to be executed by only one thread you declare it with synchronized keyword.
What about classes, how to provide a lock on an entire class of objects when a thread
is executing some code on an instance of that class?
In other words, when a thread is executing a method on an object, no other thread should be
allowed to execute the same method even on a different instance of the same class.
You synchronize on a specific object, either some designated static lock object, or the class object (which happens when static methods are declared to be synchronized):
class X {
private static final Object lock = new Object();
public void oneAtATime() {
synchronized (lock) {
// Do stuff
}
}
}
class Y {
public void oneAtATime() {
synchronized (Y.class) {
// Do stuff
}
}
}
Each variant has its own pros and cons; locking on the class allows other code, outside of the class, to use the same lock for its own reasons (which allows it to orchestrate more high-level synchronization than what you provide) while the static final Object lock approach lets you prohibits it by making the lock field private (which makes it easier to reason about the locking and avoid your code from deadlocking because someone else wrote bad code).
You could of course also use some synchronization mechanism from java.util.concurrent, like explicit Locks, which provide more control over locking (and ReentrantLock currently performs a little better than implicit locks under high contention).
Edit: Note that static/global locks aren't a great way to go - it means every instance of the class ever created will essentially be tied to every other instance (which, aside from making it harder to test or read the code, can severely harm scalability). I assume you do this to synchronize some kind of global state? In that case, I'd consider wrapping that global/static state in a class instead, and implement synchronization per-instance rather than globally.
Instead of something like this:
class Z {
private static int state;
public void oneAtATime(){
synchronized (Z.class) {
state++;
}
}
}
Do it like this:
class State {
private int value;
public synchronized void mutate(){ value++; }
}
class Z {
private final State state;
public Z(State state){
this.state = state;
}
public void oneAtATime(){
state.mutate();
}
}
// Usage:
State s1 = new State(), s2 = new State();
Z foo = new Z(s1);
Z bar = new Z(s1);
Z frob = new Z(s2);
Z quux = new Z(s2);
Now foo and bar are still tied to each other, but they can work independently from frob and quux.
If you use static synchronized methods, they are locked via the Class Lock. You can also declare a static Object in the class and lock that in a method I believe via something like:
private static final Object STATIC_LOCK = new Object();
private void foo() {
synchronized (STATIC_LOCK) {
//do stuff...
}
}
You could use a static Mutex inside that method. So any concurrent thread is blocking inside the method while another is running it no matter what object of the class it belongs to. I don't think there is any special single keyword to produce the same effect like synchronized.
It is a rather aggressive synchronization, I would avoid it as much as possible.
Synchronize on static field of your class, or the class itself:
synchronized(MyClass.class) {
// mutually excluded method body
}
Both threads must use this construction
public void someMethod() {
synchronized(ClassThatShouldBeProtected.class) {
someSynchronizedCode();
}
}
This approach benefits from the fact, that class itself is an object and therefore it has a monitor. Then you don't need any artificial static instance.
There is no built-in mechanism for this. Create your own static lock attribute, and make sure you lock it and unlock it in every method. Don't forget about exceptions - make sure you unlock it in the "finally" sections.
This should work:
public class MyClass {
void synchronizedMethod() {
synchronized (MyClass.class) {
// synchronized on static level
}
}
}
Which 'missuses' the class's runtime-representation for locking. This is possible as any object can be used as a mutex in Java.
http://www.janeg.ca/scjp/threads/synchronization.html
talks about several ways to achieve it.
in general, locks are prohibitive and hinder benefits of threading. so the critical code should be minimized as much as its possible.
do you want a class lever lock to access static variables of the class or is it for protecting access to a common external resource the class? in which case you should proly have a separate lock while accessing it.

Categories