views:

218

answers:

8

consider this class,with no instance variables and only methods which are non-synchronous can we infer from this info that this class in Thread-safe?

public class test{

public void test1{

// do something

}

public void test2{

// do something


}

public void test3{

// do something

}



}
A: 

yes, as long as there are no instance variables. method calls using only input parameters and local variables are inherently thread-safe. you might consider making the methods static too, to reflect this.

oedo
A: 

If it has no mutable state - it's thread safe. If you have no state - you're thread safe by association.

Bozhidar Batsov
Unfortunately it's not quite that simple - see the other answers.
Péter Török
+5  A: 

It depends entirely on what state the methods mutate. If they mutate no shared state, they're thread safe. If they mutate only local state, they're thread-safe. If they only call methods that are thread-safe, they're thread-safe.

HTH,
Kent

Kent Boogaart
You can extend that to also accessing `ThreadLocal` instances. They're a good way to have state that exists for more than the scope of a call while not having thread hazards.
Donal Fellows
+1  A: 

Depends on what happens inside those methods. If they manipulate / call any method parameters or global variables / singletons which are not themselves thread safe, the class is not thread safe either.

(yes I see that the methods as shown here here have no parameters, but no brackets either, so this is obviously not full working code - it wouldn't even compile as is.)

Péter Török
A: 

No, I don't think so.

For example, one of the methods could obtain a (non-thread-safe) singleton object from another class and mutate that object.

David Gelhar
+1  A: 

I recommend reading the following article about thread safety: Java theory and practice: Characterizing thread safety. A quote:

In reality, any definition of thread safety is going to have a certain degree of circularity, as it must appeal to the class's specification -- which is an informal, prose description of what the class does, its side effects, which states are valid or invalid, invariants, preconditions, postconditions, and so on. (Constraints on an object's state imposed by the specification apply only to the externally visible state -- that which can be observed by calling its public methods and accessing its public fields -- rather than its internal state, which is what is actually represented in its private fields.)

Thread safety

For a class to be thread-safe, it first must behave correctly in a single-threaded environment. If a class is correctly implemented, which is another way of saying that it conforms to its specification, no sequence of operations (reads or writes of public fields and calls to public methods) on objects of that class should be able to put the object into an invalid state, observe the object to be in an invalid state, or violate any of the class's invariants, preconditions, or postconditions.

Furthermore, for a class to be thread-safe, it must continue to behave correctly, in the sense described above, when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, without any additional synchronization on the part of the calling code. The effect is that operations on a thread-safe object will appear to all threads to occur in a fixed, globally consistent order.

So your class itself is thread-safe, as long as it doesn't have any side effects. As soon as the methods mutate any external objects (e.g. some singletons, as already mentioned by others) it's not any longer thread-safe.

MicSim
+2  A: 

Not being thread safe means that if multiple threads try to access the object at the same time, something might change from one access to the next, and cause issues. Consider the following:

int incrementCount() {
    this.count++;
    // ... Do some other stuff
    return this.count;
}

would not be thread safe. Why is it not? Imagine thread 1 accesses it, count is increased, then some processing occurs. While going through the function, another thread accesses it, increasing count again. The first thread, which had it go from, say, 1 to 2, would now have it go from 1 to 3 when it returns. Thread 2 would see it go from 1 to 3 as well, so what happened to 2?

In this case, you would want something like this (keeping in mind that this isn't any language-specific code, but closest to Java, one of only 2 I've done threading in)

int incrementCount() synchronized {
    this.count++;
    // ... Do some other stuff
    return this.count;
}

The synchronized keyword here would make sure that as long as one thread is accessing it, no other threads could. This would mean that thread 1 hits it, count goes from 1 to 2, as expected. Thread 2 hits it while 1 is processing, it has to wait until thread 1 is done. When it's done, thread 1 gets a return of 2, then thread 2 goes throguh, and gets the expected 3.

Now, an example, similar to what you have there, that would be entirely thread-safe, no matter what:

int incrementCount(int count) {
    count++;
    // ... Do some other stuff
    return this.count;
}

As the only variables being touched here are fully local to the function, there is no case where two threads accessing it at the same time could try working with data changed from the other. This would make it thread safe.

So, to answer the question, assuming that the functions don't modify anything outside of the specific called function, then yes, the class could be deemed to be thread-safe.

Slokun
A: 

Yes - this class is thread safe but this does not mean that your application is.

An application is thread safe if the threads in it cannot concurrently access heap state. All objects in Java (and therefore all of their fields) are created on the heap. So, if there are no fields in an object then it is thread safe.

In any practical application, objects will have state. If you can guarantee that these objects are not accessed concurrently then you have a thread safe application.

There are ways of optimizing access to shared state e.g. Atomic variables or with carful use of the volatile keyword, but I think this is going beyond what you've asked.

I hope this helps.

Steve Neal