First class:
class Main1 {
private ExecutorService service = Executors.newFixedThreadPool(4);
public static void main(String[] args) {
Main1 m = new Main1();
m.start();
}
public void start() {
final MyObject obj = new MyObject();
obj.doSomeCalculation();// after this point not to modify obj in main thread
service.submit(new Runnable(){
public void run() {
obj.doSomething(); // is it threadsafe doing this?
}
});
}
}
Second class:
class Main2 {
private ExecutorService service = Executors.newFixedThreadPool(4);
public static void main(String[] args) {
Main2 m = new Main2();
m.start();
}
public void start() {
class Job implements Runnable {
public MyObject obj;
public void run() {
obj.doSomething(); // is it threadsafe doing this?
}
}
Job job = new Job();
job.obj.doSomeCalculation(); // after this point not to modify obj in main thread
service.submit(job);
}
}
Are Main1 and Main2 threadsafe? Does Main1 and Main2 make different sense to thread-safety?
update:
neither doSomeCalulation() nor doSomething() don't have any lock or synchronized block. I want to known whether doSomething() could always read the correct states that doSomeCalculation() change to obj
Are Main1, Main2 threadsafe?
In the Main1 case, the thread-safety of the application depends on whether MyObject is thread-safe and whether any other threads doing things with it. However, the obj.doSomething(); statement is thread-safe assuming nothing else is changing the object
In fact, the obj.doSomething(); statement doesn't use the variable in the enclosing class. Instead, the value of that variable is passed to the inner class in a hidden constructor argument. The other thing that makes this thread-safe is that there is an implicit synchronization between the parent and child threads when a new thread is created. (Reference - JLS 17.4.4 Synchronization Order) These two facts combined mean that the Runnable.run() method will get the correct reference, and that the child thread will see the state of the object at the synchronization point (or later).
In the Main2 case, the same applies. In this case you are merely doing explicitly (more or less) what is happening implicitly in the Main1 case.
UPDATE - the above reasoning applies even if you mutate the object in the parent thread (as per your updated question) before passing it to the child thread ... because of the implicit synchronization that I mentioned. (However, if the parent thread were to change MyObject after the submit() call, you'd run into thread-safety problems.)
Does Main1 and Main2 make different sense?
I don't know what you are asking. If you are asking if there is any benefit in using an inner class rather than an anonymous inner class ... in this case the answer is no. They behave the same with respect to thread-safety.
Actually, the Main1 version is better because its is simpler, more readable (to an experienced Java developer), and more robust. The Main2 class exposes the obj field for other code to potentially access or even update. That's bad style. You could fix that, but only by adding more code ... which brings us back to simplicity / readability.
The way your code is structured, you submit your job (in both cases) only after you have already performed the calculation above. So there is no chance of those two actions happening in parallel and so there are no data races.
However, if you were to perform your calculations after submitting the job/Runnable to the executor service, then those two calculations could happen in parallel and there could be a data race.
Job job = new Job();
service.submit(job);
// Now there is a data race!!!
job.obj = ...// do some calculation, and after this point not to modify obj in main thread
Related
I'm trying to understand whether this is thread safe. I believe it is, but someone recently brought into question the thread safety of this method.
Let's say I have some factory FactoryA that give us a class which implements the following interface:
public abstract class MyFactory {
private ObjectA object;
public void init(ObjectA object){
_object = object;
}
}
So, we have something like
public class FactoryA extends MyFactory {
static final createFactoryClass(String name) {
// ...ignorning safety checks for brevity
return MY_MAP.get(name).newInstance();
}
}
Now, I have some method in another class that takes the factory and gives back a map of possible classes:
public class OtherClass {
private static FactoryA _factory = new FactoryA();
private static final Map<String, SomeClass> MY_MAP = new ImmutableMap.Builder<String, MyClass>()
.put("foo", _factory.createFactoryClass("foo"));
private SomeObject myMethod(ObjectA objectA, SomeObject someObject) {
MY_MAP.get(someObject.getString()).init(objectA);
}
}
The question is whether the init method is thread safe. The map is initialized only once, so even though it's stored in an immutable structure, if two threads call it with different ObjectA, is it possible for the wrong class to use the wrong ObjectA?
Can I just fix this possible problem by doing the following?
private static synchronized myMethod(...) {}
Local variables are always thread-safe, unless the variable is a reference to an object which is shared, i.e. like in the following example:
static void setValue(Example obj, int val) {
obj.val = val;
}
Example sharedObj = ...;
new Thread(() -> { setValue(sharedObj, 1); }).start();
new Thread(() -> { setValue(sharedObj, 2); }).start();
In that example, though, it's not the use of the reference to sharedObj per se which is unsafe, it's the fact that we used that reference to change the state of sharedObj.val concurrently.
If instead we had two threads which have references to different objects:
Thread threadA = new Thread(() -> {
Example objA = ...;
setValue(objA, 1);
});
Thread threadB = new Thread(() -> {
Example objB = ...;
setValue(objB, 2);
});
threadA.start();
threadB.start();
The JVM won't get confused and pass e.g. threadA's object to threadB's invocation of setValue, or vice-versa. That's kind of what it sounds like you are asking, and that won't happen. Every thread has its own call stack and each thread's invocation of setValue opens a new stack frame on its own thread. In other words, threadA calls setValue which creates a stack frame on threadA with its own local variables, and threadB calls setValue which creates a stack frame on threadB with its own local variables.
There is a separate concern which is that the changes your init method makes may not be seen by other threads. For example, say you have a Thread thread1 whose job it is to initialize objects by passing them to init, and then pass those objects to some other Thread thread2. Will thread2 see the changes which init made to the objects on thread1? The answer is no, without some sort of memory synchronization, thread2 may not see the changes which were made during thread1's call to init.
Making myMethod synchronized probably doesn't solve that problem, though. Instead, thread1 and thread2 need some way to communicate, like a shared monitor object or lock.
There's a third issue which I guess you are hinting at, which is about the initialization of the map. If the map is built only during a static initializer, then it's thread-safe, because class initialization is performed under synchronization and:
An implementation may optimize this procedure by eliding the lock acquisition [...] when it can determine that the initialization of the class has already completed, provided that, in terms of the memory model, all happens-before orderings that would exist if the lock were acquired, still exist when the optimization is performed.
In other words, static initialization is guaranteed to be seen by other threads, even if the JVM decides that it's been awhile since a particular class has been initialized and decides to read the field without trying to acquire the initialization lock.
I would suggest different naming for the classes/methods, as currently it is difficult to understand what is going on. Also I would make the factories into singletons.
import java.util.HashMap;
import java.util.Map;
public class FactoryStore {
private static final Map<String, AbstractFactory> FACTORIES = new HashMap<>();
static {
FACTORIES.put("a", FactoryA.getInstance());
FACTORIES.put("b", FactoryB.getInstance());
}
public static Object createObject(String factoryName, Object parameters) {
return FACTORIES.get(factoryName).createNewObject(parameters);
}
}
abstract class AbstractFactory {
Object createNewObject(Object parameters) {
// not thread-safe stuff
return new Object();
}
}
class FactoryA extends AbstractFactory {
private static final FactoryA instance = new FactoryA();
private FactoryA() {
// thread safe stuff
}
public static FactoryA getInstance() {
return instance;
}
}
class FactoryB extends AbstractFactory {
private static final FactoryB instance = new FactoryB();
private FactoryB() {
// thread safe stuff
}
public static FactoryB getInstance() {
return instance;
}
#Override
synchronized Object createNewObject(Object obj) {
// can override object creation; this is thread-safe thanks to keyword
return new Object();
}
}
I got a crash report from a user with seems rather impossible. The stacktrace indicate that a object was null and he got a nullpointerException.
(here is the line if you want to see)
public class City extends Unit {
private ArrayList<SolderType> Queue = new ArrayList<SolderType>();
public float getPrecentCompleted()
{
if(Queue.isEmpty())
{
return 0f;
}
//More code that is not relevent
}
}
It doesn't leave out much to interpret Queue was probably null, however Queue is only create at one place in my code and that is in the constructor. So i don't see how it can be null. The object is shared over more then one thread and new objects are created all the time. But the Queue point can only be set at the creation of the object. So i don't see how this is possible. Is it possible for one thread to call on a objects method while an other is created the object but not done?
EDIT Added some more code that might be relevant to the question.
The comment gives the correct answer: Yes, that is possible, unless you've added synchronisation to prevent it. The only operations wich define an order between two threads are the following (see https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.4):
An unlock action on monitor m synchronizes-with all subsequent lock
actions on m (where "subsequent" is defined according to the
synchronization order).
A write to a volatile variable v (§8.3.1.4) synchronizes-with all
subsequent reads of v by any thread (where "subsequent" is defined
according to the synchronization order).
An action that starts a thread synchronizes-with the first action in
the thread it starts.
The write of the default value (zero, false, or null) to each
variable synchronizes-with the first action in every thread. Although it may seem a little strange to write a default value to a variable before the object containing the variable is allocated, conceptually every object is created at the start of the program with its default initialized values.
The final action in a thread T1 synchronizes-with any action in
another thread T2 that detects that T1 has terminated.
If thread T1 interrupts thread T2, the interrupt by T1
synchronizes-with any point where any other thread (including T2)
determines that T2 has been interrupted (by having an
InterruptedException thrown or by invoking Thread.interrupted or
Thread.isInterrupted).
Without such an operation you will see the object in other threads in an undefined state.
On way to solve the null pointer exception is to use a final field (see https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5). But you must also synchronize ArrayList. I suggest to use a queue from the java.util.concurrent package.
The most common cause for such situation is calling an overridden method from superclass constructor like this:
import java.util.ArrayList;
public class NPEInheritance {
static class Parent {
Parent() {
validate();
}
void validate() {}
}
static class Child extends Parent {
private ArrayList<Object> Queue;
Child() {
Queue = new ArrayList<>();
}
#Override
void validate() {
if(Queue.isEmpty()) {
System.out.println("Queue is empty");
}
}
}
public static void main(String[] args) {
new Child();
}
}
When you run this code, you will see such "impossible NullPointerException". As you can see, here Parent constructor calls method which is overridden in Child class and overridden method uses the field which is not initialized yet as Child constructor has still not executed.
I think that when you create the Child Object the first thing it does its to initializate the parent Object (because it extends) and when your parent object tries to validate its twhen you get NullPointer.
I think you need to put your Queue object into the parent something like this.
import java.util.ArrayList;
public class NPEInheritance {
static class Parent {
protected ArrayList<Object> Queue;
Parent() {
Queue = new ArrayList<>();
validate();
}
void validate() {}
}
static class Child extends Parent {
Child() {
}
#Override
void validate() {
if(Queue.isEmpty()) {
System.out.println("Queue is empty");
}
}
}
public static void main(String[] args) {
new Child();
}
}
A particular case to watch out for arises when class A's static initialization creates or references a (possibly static) instance of class B, and B's static initialization has a similar dependency on A.
Obviously, in this situation neither class can fully initialize before the other.
Java silently breaks the deadlock by allowing one of the classes to return uninitialized values. As a result, with no warning, you may see "impossible" zeros or nulls. Since this dependency loop may go through several other classes it can be a real pain to track down even if you know this risk exists.
The fix is generally to refactor some or all of the static objects involved into a third class, making the dependency graph a tree again. Easy and obvious once you're found the problem. Better, of course, to avoid creating the problem in the first place.
According to the Java Language Specification, constructors cannot be marked synchronized because other threads cannot see the object being created until the thread creating it has finished it. This seems a bit odd, because I can indeed have another thread view the object while it's being constructed:
public class Test {
public Test() {
final Test me = this;
new Thread() {
#Override
public void run() {
// ... Reference 'me,' the object being constructed
}
}.start();
}
}
I know that this is a pretty contrived example, but it seems in theory that someone could come up with a more realistic case where marking the constructor synchronized would be legitimate in order to prevent races with threads like this one.
My question is this: is there a reason that Java would specifically disallow the synchronized modifier on a constructor? Perhaps my above example is flawed, or perhaps there really is no reason and it's an arbitrary design decision. In either case, I'm really curious and would love to know the answer.
If you really need synchronization of the rest of the constructor versus any threads which anyhow gets a reference to your not-yet-totally-constructed object, you can use a synchronized-block:
public class Test {
public Test() {
final Test me = this;
synchronized(this) {
new Thread() {
#Override
public void run() {
// ... Reference 'me,' the object being constructed
synchronized(me) {
// do something dangerous with 'me'.
}
}
}.start();
// do something dangerous with this
}
}
}
Usually it is considered bad style to "give out" your not-yet-constructed object like this, so a synchronized constructor is not necessary.
In some corner cases a synchronized constructor would be useful. Here is a more realistic example, from the discussion of Bozho's answer:
public abstract class SuperClass {
public SuperClass() {
new Thread("evil") { public void run() {
doSomethingDangerous();
}}).start();
try {
Thread.sleep(5000);
}
catch(InterruptedException ex) { /* ignore */ }
}
public abstract void doSomethingDangerous();
}
public class SubClass extends SuperClass {
int number;
public SubClass () {
super();
number = 2;
}
public synchronized void doSomethingDangerous() {
if(number == 2) {
System.out.println("everything OK");
}
else {
System.out.println("we have a problem.");
}
}
}
We want that the doSomethingDangerous() method is only called after construction of our SubClass object is complete, e.g. we only want the "everything OK" output. But in this case, when you only can edit your SubClass, you have no chance of achieving this. If the constructor could be synchronized, it would solve the problem.
So, what we learn about this: never do something like I did here in the superclass constructor, if your class is not final - and don't call any non-final methods of your own class from your constructor.
The question has been raised on a discussion list used by the writers of the Java concurrent API and the Java Memory Model. Several answers were given, in particular Hans Boehm replied:
Some of us (myself included IIRC) actually argued during the Java memory model deliberations that synchronized constructors should be allowed. Now I could go either way on it. Client code shouldn't use races to communicate the reference, so it shouldn't matter. But if you don't trust the clients of [your class], I think synchronized constructors could possibly be useful. And that was much of the reasoning behind final field semantics. [...] As David said, you can use synchronized blocks.
Because synchronized guarantees that actions on the same objects are not to be performed by multiple threads. And when the constructor is called you still don't have the object. It is logically impossible for two threads to access the constructor of the same object.
In your example, even if a method is invoked by the new thread, it is no longer about the constructor - it is about the target method being synchronized or not.
Constructor Modifiers section in JLS clearly says
There is no practical need for a constructor to be synchronized, because it would
lock the object under construction, which is normally not made available to other
threads until all constructors for the object have completed their work.
So there is no need for constructor to be synchronized.
Also it is not recommended to give out the objects reference(this) before object is created. One of the possible ambiguous situations would be to give out the objects reference is superclass constructor when subsclass object is being created.
In your example, the constructor is only actually called once from one thread.
Yes, it is possible to get a reference to an incompletely constructed Object (some discussions around double check locking and why it is broken reveal this problem), however, not by calling the constructor a second time.
Syncronized on the constructor would prevent two threads from calling the constructor on the same Object simultaneously, and that is not possible, as it is never possible to call the constructor on an object instance twice, period.
I see little reason to forbid constructors to be synchronized. It would be useful in many scenarios in multi-threaded applications. If I understand the Java Memory Model correctly (I read http://jeremymanson.blogspot.se/2008/11/what-volatile-means-in-java.html) the following simple class could have benefited from a synchronized constructor.
public class A {
private int myInt;
public /*synchronized*/ A() {
myInt = 3;
}
public synchronized void print() {
System.out.println(myInt);
}
}
In theory, I believe a call to print() could print "0". This could happen if an instance of A is created by Thread 1, the reference to the instance is shared with Thread 2, and Thread 2 calls print(). If there is no special synchronization between the write myInt = 3 of Thread 1 and the read of the same field by Thread 2, Thread 2 is not guaranteed to see the write.
A synchronized constructor would fix this issue. Am I right about this?
The following code can achieve the expected result for synchronized constructor.
public class SynchronisedConstructor implements Runnable {
private int myInt;
/*synchronized*/ static {
System.out.println("Within static block");
}
public SynchronisedConstructor(){
super();
synchronized(this){
System.out.println("Within sync block in constructor");
myInt = 3;
}
}
#Override
public void run() {
print();
}
public synchronized void print() {
System.out.println(Thread.currentThread().getName());
System.out.println(myInt);
}
public static void main(String[] args) {
SynchronisedConstructor sc = new SynchronisedConstructor();
Thread t1 = new Thread(sc);
t1.setName("t1");
Thread t2 = new Thread(sc);
t2.setName("t2");
t1.start();
t2.start();
}
}
Such a synchronization might make sense in some very rare cases, but I guess, it's just not worth it:
you can always use a synchronized block instead
it'd support coding in a pretty strange way
on what should it synchronize? A constructor is a sort-of static method, it works on an object but gets called without it. So synchronizing on the class also makes (some) sense!
When in doubt, leave it out.
Note that constructors cannot be synchronized — using the synchronizedkeyword with a constructor is a syntax error. Synchronizing constructors doesn't make sense, because only the thread that creates an object should have access to it while it is being constructed.
This may be a simple question,but still it is a problem for me.I am having a class that have method called task and i want to ensure only one instance of this class can run this method at a time.I have implemented it like this and am i doing it correct way?
class A{
public void task(){
synchronized(A.this){
//method stuff
}
}
}
class B{
public static void main(String a[]){
new A().task();
}
}
class C{
public static void main(String a[]){
new A().task();
}
}
If B started the task and before it completes C also came to task i want to C to wait until B completes.
so far it seems works.But i want to know is this the correct way,
thank you.
Not quite. As you have it, you guarantee that only one thread will execute task() on a given instance at a time -- but separate instances can still run task() at the same time. That is, if you did this (in pseudo-code):
Thread t1 = new A().task();
Thread t2 = new A().task();
t1.start();
t2.start();
Then since each thread creates a separate instance of A, they'll each be able to run task() at the same time.
You need to synchronize on a static field (or A.class), or make task() a static, synchronized method (in which case synchronized locks based off of the Class object).
synchronized(A.this) will rely on your instance of A.
In your case, that instance could be different i.e a thread running B.main() and another thread running C.main() will both create a different instance of A. Therefore one of them will be able to access public void task() even though it's already being accessed by the other one.
If you only want to make sure that one thread at a time can access that task method, you can do it this way:
class A{
private static final Object myLock = new Object ();
public void task() {
synchronized(myLock) {
//method stuff
}
}
}
You could also have a look at the Locks.
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.