I am just playing around with threads in java. I have a class which implements runnable.
public class MyThread implements Runnable{
private boolean finished;
//Other variables
public void run(){
//Thread code
}
}
My understanding is that each thread of type MyThread will have its own copy of member variables and writes to those member variables need not be synchronized. Is this assumption correct? If correct, access to what needs to be synchronized? Can someone care to give a outline or pseudo code.? Thanks.
Not necessarily. You could create multiple threads using the same instance of MyThread. For example:
MyThread x = new MyThread();
new Thread(x).start();
new Thread(x).start();
new Thread(x).start();
Now there will be three threads all running code in the same object.
I suggest you rename MyThread as it's not a thread - it's a task for a thread to perform. That makes it clearer (IMO).
Each MyThread instance is a new instance, just like normal classes and objects.
Variables of native types are copied. This means that changing the variable in one thread does nothing to the other thread. These do not have to be synchronized.
For objects their references are copied. This means that two threads may have a reference to the same object. If the two threads manipulate that object at the same time, this can go bad. Therefore, these accesses have to be synchronized.
The Really Big Index trail on concurrency is well worth a read (yes, it has examples).
Related
I have a code which is as below
class classA {
int sum = 0;
void recursiveMethodA {
sum = sum +1; // For simplicity
}
}
Basically I am doing some operation in a recursive method which runs lets say 10 times and changing state at class level. But this class is not thread safe.
Now in order to make it thread safe I am thinking of a below option.
class class B {
// Public exposed method
public void methodB {
ClassA classA = new ClassA();
classA.recursiveMethodA();
}
}
My logic is that since I am creating object of class A inside a method of class B, it is created on stack instead of heap and hence it is thread safe.
Is this logic correct? Please suggest alternate options.
My logic is that since I am creating object of class A inside a method of class B, it is created on stack instead of heap and hence it is thread safe.
Your logic and/or terminology are not correct. In fact, the instance of ClassA is in the heap. All regular Java objects are created in the heap!
Your code is actually thread-safe, but the correct explanation is as follows:
The object is created, and the only reference to it is assigned to a local variable.
By inspection, no other thread can ever see that variable.
By inspection, the object reference is never passed to another thread; i.e. it is not published.
The points 1., 2., and 3. mean that the object is thread confined1 for its entire lifetime.
Since the object is thread confined, it is not necessary to consider thread-safety.
It is not sufficient to say (just) that a local variable is used:
There are scenarios where another thread can see the value of a local variable; e.g. if a lambda or inner method closure is created and passed to another thread.
It is also necessary to consider that the value in the variable could be passed to another thread.
Finalization and reference processing will be done on another thread. However, this should NOT present a thread-safety concern. (The JLS spec takes care of finalization, and the javadocs for Reference take care of references. In both cases, there is a happens before at the appropriate points.)
1 - This is a fancy way of saying that no other thread can ever see it the object and its reference.
Do you mean classA is thread safe by itself?
No. It is not thread safe by itself. It is thread safe in this particular context. Or more to the point, thread safety is moot in this context ... because the instance is thread confined.
Shouldn't I define the class as thread safe in all the contexts? I don't know how tomorrow it can be used?
That is up to you!
But consider this: a large number of standard Java classes are NOT thread-safe ... by design. Indeed the classic case is StringBuilder which is the non-thread-safe reimplementation of StringBuffer. Others are most of the collection types in java.util!
Basically, you have two choices:
Make a class inherently thread-safe, and accept that this comes with runtime overheads.
Make a class inherently non-thread-safe, and make sure that you only use it ways that deal with this appropriately. (One way is to thread confine the instances. Another is to use some form of external synchronization.)
The simplest way to have a threadsafe function is put keyword "synchronized"
synchronized public void method() {
//do something
}
What does this java code mean? Will it gain lock on all objects of MyClass?
synchronized(MyClass.class) {
//is all objects of MyClass are thread-safe now ??
}
And how the above code differs from this one:
synchronized(this) {
//is all objects of MyClass are thread-safe now ??
}
The snippet synchronized(X.class) uses the class instance as a monitor. As there is only one class instance (the object representing the class metadata at runtime) one thread can be in this block.
With synchronized(this) the block is guarded by the instance. For every instance only one thread may enter the block.
synchronized(X.class) is used to make sure that there is exactly one Thread in the block. synchronized(this) ensures that there is exactly one thread per instance. If this makes the actual code in the block thread-safe depends on the implementation. If mutate only state of the instance synchronized(this) is enough.
To add to the other answers:
static void myMethod() {
synchronized(MyClass.class) {
//code
}
}
is equivalent to
static synchronized void myMethod() {
//code
}
and
void myMethod() {
synchronized(this) {
//code
}
}
is equivalent to
synchronized void myMethod() {
//code
}
No, the first will get a lock on the class definition of MyClass, not all instances of it. However, if used in an instance, this will effectively block all other instances, since they share a single class definition.
The second will get a lock on the current instance only.
As to whether this makes your objects thread safe, that is a far more complex question - we'd need to see your code!
Yes it will (on any synchronized block/function).
I was wondering about this question for couple days for myself (actually in kotlin). I finally found good explanation and want to share it:
Class level lock prevents multiple threads to enter in synchronized block in any of all available instances of the class on runtime. This means if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads.
Class level locking should always be done to make static data thread safe. As we know that static keyword associate data of methods to class level, so use locking at static fields or methods to make it on class level.
Plus to notice why .class. It is just because .class is equivalent to any static variable of class similar to:
private final static Object lock = new Object();
where lock variable name is class and type is Class<T>
Read more:
https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/
public class TestThread {
ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
TestThread testThread = new TestThread();
final List<String> list = new ArrayList<>();
Runnable runnable = new Runnable() {
#Override
public void run() {
System.out.print(list);
}
}
testThread.executorService.submit(runnable);
}
}
In this code code snippet, a list is created in main thread. And in a runnable instance will access this list in other threads which were managed by ExecutorService.
So my question is if there will be thread memory visibility issue in this case? As I know a thread can not see(or completely see) the value in another thread if sychronization/volatile not being used.
The reason you have to make that variable final is that your Runnable can be created with a copy of it (which is also final).
final fields initialized during object construction are guaranteed to be published properly to all threads.
So it will see the list.
However, ArrayList is not thread-safe, so you should not be sharing it with multiple threads (if you plan to modify it).
It may be useful to show a little about how anonymous classes are implemented, and how they access local variables.
Your Runnable class here would be converted by the compiler into a new "named" class, which looks something like:
class TestThread$1 implements Runnable {
private final List<String> list;
TestThread$1(List<String> list) {
this.list = list;
}
#Override
public void run() {
System.out.println(list);
}
}
and the line where you instantiate it would be converted to:
Runnable runnable = new TestThread$1(list);
As such, the list reference used inside the anonymous class is actually not the same reference as the list reference in the main method - it just so happens to point to the same instance, and has the same name.
The requirement for variables referred to in anonymous classes to be final ensures that these two variables will point to the same instance forever after, since you can't reassign either one of them. (See Why are only final variables accessible in anonymous class?)
Now, as noted by Thilo, final member variables are guaranteed to be visible to all threads when the constructor finishes. The above code shows that there is a constructor here, which assigns a final variable. As such, the list reference available inside the body of the run() is guaranteed to be visible and consistent to all threads.
However, this makes no guarantees about the visibility and consistency of the list's internal variables. As stated in the Javadoc for ArrayList:
Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.
Hence, external synchronization may be required, depending upon what you do with the list in any of the threads which have a reference to it (whether that is the main thread or any thread running the Runnable).
I think you've only partially understood the problem. All threads would be able to "see" the list. The problem is what they "see". Unless you either make sure that the list is not modified once the threads are started or make sure to synchronize access to the list (or any data structure that is accessed by multiple threads) then you run the risk of experiencing inconsistencies or in the worst case memory corruption.
The volatile keyword is not enough. You will need to synchronize access to the list using synchronized blocks of code, or some other synchronization primitive (monitor, semaphore etc.)
Is it possible to synchronize the method when we extend Thread rather than implementing Runnable?
I know that when we use Runnable, it is possible. But when we do Thread t1 = new Thread();, can this be done?
How can it be synchronized?
Synchronization is orthogonal to the class on which the method is defined. You can use synchronized in any method. It just means there's a mutex guarding that block of code.
public class MyTotallyUnspecialClass {
synchronized public void someTotallyUnspecialMethod() {
// this method is synchronized, with a mutex on "this"
}
}
There is no effect on synchronization whether you extend Thread or implement Runnable. When you synchronize a method , you get a lock on the OBJECT and not the thread - so it really does not matter.There are many SO topics that discuss the distinction between these 2 approaches (extending thread vs implementing Runnable)
I'm working on a TCP socket right now.
I derive my server class from Thread.
public class TCPServer extends Thread {
public static int SERVERPORT = 54321;
....
<code>
}
When I use this class, it will open several threads. My question is, does each thread have its own static variable SERVERPORT?
Because it seems like if I edit this variable, it does not have effect in others.
My solution to this problem would be to create another class, say "GlobalVariables" and give this class access to it.
My question is, does each thread have its own static variable SERVERPORT?
No, it does not. The variable is shared by all threads in the process.
I missed removing the final :D The variable I have is of type static boolean
Even though the variable is shared, when you modify it in one thread, the change won't necessarily become visible to other threads until some later, unspecified, time.
You need to take steps to ensure visibility. Depending on what your code is doing, this can include:
explicit synchronization;
using a volatile boolean;
using AtomicBoolean.