I tried really hard to search for information about the issue, but nothing was relevant.
Any contribution will be appreciated.
DataStructure ds = new DataStructure();
public synchronized void run() { b(); }
private void b() { ds.update(); }
public synchronized void c() { ds.update(); }
Suppose that the above code is implemented using a thread.
as you might notice, there is a DataStructure object which is being shared and accessed through synchronized methods, when only one synchronized method can be called at any given time (I am not mistaken. right?).
Is there any possibility that the DataStructure object will be accessed through the public methods in unsynchronized manner?
thanks.
Your code is incomplete, but if the above is part of a Runnable or Thread, then no concurrency is possible with the given methods since you're synchronizing the entire run() method. Using threads is pretty pointless in that case.
I also don't see where the DataStructure would be shared between threads - looks like a separate one is created for each one. If it actually is shared, then access would not be synchronized because you synchronize on the Runnable or Thread rather than the shared object.
Without seeing more code, its very hard to tell. What is the class that those methods belong to? how are they invoked, and by what classes?
Concurrency problems are hard to diagnose, and harder if there isn't enough information.
What i assume you have are threads that execute the run() method above, and there are different threads that execute the c() method. The synchronization happens on the class that the above method resides, so there wouldn't be any problems (except slowness if lots of threads).
If
There is no other public method apart from what you wrote here, that has access to ds, and
"the DataStructure object" you are talking on is the object instance in a specific object instance of your class (instead of ALL DataStructure objects)
then what you are expecting is correct. There shouldn't be any concurrent access to ds through public methods of your class.
Honestly I don't see anything special in your class that make it different from normal synchronized method example.
Related
Say I have class A which is not thread safe, and I want to launch a bunch of threads with class B, is passing a new instance of class A to each thread of class B a good design choice, since if I passed one instance of class A to all of them there would be concurrency issues?
#NotThreadSafe
class A {
...
}
class B extends Thread {
private A a;
B(A a) {
this.a = a;
}
}
class C {
public static void main(String [] args) {
for(int i = 0; i < 10; i++) {
A a = new A();
B b = new B(a);
b.start();
}
}
}
It pretty much depends on the characteristics of class A.
In general, passing creating an instance of A per thread will solve (not solve, but rather eliminate) concurrency issues.
Assuming class A has some internal state (otherwise class A itself is supposed to be thread safe), each thread B will read/update different fields in memory that belong to its "own" object of class A, so no concurrency issue here, unless...
A is very "heavy" object and creating it will have a big performance / memory impact.
Using design of object per thread won't meet the functional requirements of the product. For example, you have to share something between threads (somthing = some common state) because if one thread B, say, has done some work and has updated that internal state, another thread B should be able to benefit from (be able to read) that state otherwise it will do that work again or do it in a wrong.
Let's assume that you have overridden run in the B class. Your example doesn't make sense otherwise. (The start() call would invoke Thread::run which returns immediately. Ooops!)
Some terminology first.
A thread confined object is an object is an object whose state is accessible to one and only one thread.
If an object is thread confined, then it doesn't matter if the class is thread-safe or not.
(Depending on how broadly you define "state" of course. Lets assume that the object's state is the closure of the object that the object's methods may access. Or something like that.)
So what we have in your example is a non-thread-safe object a that is created in main and then used solely in a single child thread.
Prior to the start() call, each a is thread confined to the main thread. For this part of the program, thread-safety (of A) doesn't matter.
Once control reaches the child thread's run() method, each a is thread confined to the child thread. From then on, thread safety doesn't matter.
Now what about the start() call itself?
The Java Memory Model (JLS 17.4) specifies that there is a happens-before relationship between the call to start() in the main thread, and the call to run() in the child thread. This happens-before ensures that writes to the A or B instances or anything else made by the main thread prior to the start() call are guaranteed to be visible to the child thread on / after entering the run method body. This is a strong guarantee. Any compliant Java 5.0 or later implementation will behave this way, on any platform.
However, changes made to the A, etc in the main thread after the start() call are not guaranteed to be visible to the child. They may or may not be. If that happens, your code is likely to be broken. But the example code doesn't show it happening.
In summary, this approach is thread-safe. Whether it is "viable" depends on whether your design meets the requirements. For example, the B threads need to share state, this approach doesn't address that.
Finally, extending Thread is generally thought to be a bad idea. A better idea would be to instantiate plain Thread instances, passing them a Runnable as a constructor parameter. Alternatively, use an ExecutorService and let that take care of thread management.
There is a big difference between using a single instance and a new instance each time. (Eg if the class represents a Person then, it's the difference between the same person or a different one every time. This makes the program outcome different between circumstances and this question therefore doesn't make sense.)
If we assume the class holds no data and therefore the program outcome will not change whether or not a single instance or multiple are used, then
a good design choice, since if I passed one instance of class A to all
of them there would be concurrency issues
it would be a terrible design choice and not solve any concurrency issues, as the external data each class instance works on will still be the same and the threads will fight over the data.
To fix concurrency issues you must use synchronization.
I could not find any definitive answer to my question elsewhere so I'm deciding to ask.
I am having porting code into Java and making it threadsafe. I'm applying as many getters/setters as I can on objects and passing them around. And obviously these values are not set as static. But I'm also looking at other angles.
For any particular thread I want all methods in a class to be able to access a class variable without other threads interfering (and WITHOUT synchronized variable keyword), is the following acceptable?
public class TestClass {
public double testVal;
public void methodA() {
testVal = 22.6;
}
public double methodB() {
return testVal;
}
}
If I create an instance of TestClass in main and call methodA then methodB on that object, it returns my testVal. This problem is to be scaled up with many many values shared across different methods in the class as i'm just showing a simple demo.
Is this a good threadsafe approach? This data would be stored on the thread stack rather than the heap if I'm correct?
Cheers
There are many ways to make your class thread safe.
1. You can make your variable as volatile as in the example you have asked , if the current state of testval does not depend upon the previous state
2. You make the variable as private and volatile and use synchronization for all the methods that are modifying the state of your object.
3. Make the class as immutable
4. Make the calss as stateless
5. Guard all the method with synchronized keyword that are modifying the state of the variables.
I'm looking through the Java concurrency tutorials to get an idea of how this works in Java and had a question regarding the "MsLunch" example # http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
I'm trying to understand in the MsLunch example, the difference between coding it as shown, and using 2 synchronized methods.
From what I can understand, using the synchronized keyword on methods relies on an instrinic lock associated with that methods object. So if a class has two synchronized methods a() and b(), a() and b() cannot be called concurrently on the same object.
But coding a() and b() as shown in the MsLunch class allows both methods to be called on the same object at the same time.
Is my understanding correct?
MsLunch example uses synchronized blocks with different object instances to lock. Hence both inc1() and inc2() can run concurrently.
If it were synchronized methods, in that case this will be used to lock, methods inc1() and inc2() would be executed serially.
In http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
MSLunch is having Sync block rather than sync methods that too on two different locks so Yes Two threads will not be mutually blocked and will be able to access methods at the same time.
I am new to java thread application please tell me How to write program, every thread access same list of object in multithreading application?
is there any good link to read?
You can make sure your List (or any Collection) will be thread safe by using the relevant methods in the Collections class.
From the API:
public static <T> List<T> synchronizedList(List<T> list)
Returns a synchronized (thread-safe) list backed by the specified list.
For example
static List mySharedList = Collections.synchronizedList(new ArrayList());
Try to access your list with same instance or make it static and make it Synchronized to make your list thread-safe.
You can use a static list so that there would be only one copy at any time. Also make sure to use syncronised methods for thread-safe.
To access the same instance of your list from all threads, make it static. Eg:
private static List myList;
Then make the accessing method thread-safe (i.e. Make it so that only one thread can access it at one time, so as to avoid conflicts). Eg:
public static synchronized updateList(String parameters) {
// Do something
}
Yes, all threads are able to access the same instance of any objects (incl. classes). Because a memory space is created on per-application (i.e. per-process) basis. Then a process contains all threads inside, incl. implicit 'main' one, with shared memory space.
If an object is used in one thread only, there are no any concurrency issues. You need no any 'synchronization', locking etc. But sometimes you may have to share something between thread. If both reading and writing can be done in a few threads simultaneously, it means you need synchronize by this object to deal with so called 'racing'.
You don't have to make a field as static for a shared object to make it thread-safe. If necessary, you can just pass this object as a parameter into a class which extends Thread class (or it may be even a local variable in enclosing class method in case of anonymous class, etc.)
So all you need is just synchronize by this object. You can synchronize either explicitly inside a method:
synchronized (obj) {
// doing a thread-safe stuff
}
or you can make a method synchronized entirely for an obj's class using such method modifier. In this case it will be synchronized implicitly and automatically on invocation of the method like "synchronized (this) {..}" block:
public void synchronized methodFoo() {
}
As for reading, I read 'Java in a Nutshell', chapter 5.7. "Threads and Concurrency". It was very helpful for me because of overview of all multi-threading possibilities in Java.
Among online resources, official Sun/Oracle's tutorial may be helpful for the beginners: http://docs.oracle.com/javase/tutorial/essential/concurrency/ (which has been already mentioned in another answers).
In my project I have a game class which is called by a client class. At the moment the game class writes a path to a file and the client class will read from this file and clear the contents. I am getting too many conflicts with access here so want to use another class as the method for storing the path data. I want to know, however, if there will still be a problem, or what the outcome will be if the game class tries to call the method in the storage class to write whilst the client class at the same instant calls the method in the storage class to read and clear.
Sounds like you need to think about threading and synchronization. I'd recommend reading "Java Concurrency in Practice".
In presence of multiple threads, your classes have to be thread safe. One way of achieving this is to make the concurrently accessed methods synchronized.
Here is an example to get you started:
public class Test {
public static void main(String[] args) throws Exception {
new Thread() { public void run() { Test.method(); }}.start();
new Thread() { public void run() { Test.method(); }}.start();
}
public synchronized static void method() {
System.out.println("hello ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println("world");
}
}
Without the synchronized modifier, this program would have printed
hello
hello
world
world
With the synchronized keyword, only one thread at a time can call method, thus the program prints
hello
world
hello
world
I'm assuming your two classes are running in separate threads, so they might access the third class at the same time. The access to the resource they are reading and writing needs to be synchronized (mutexed). Java has the keyword "synchronized", which can be used in multiple ways to prevent concurrent modifications and such, see here and here for details
The theoretically correct answer is: "anything can happen".
The two calls can run one after the other or interleaved with each other, the results are unpredictable and potentially disastrous.
That's why Java offers you several ways of dealing with it.
The simplest (sounding) way is to write your methods threadsafe. In practice this usually means that you should only use local variables and must not modify the objects that are passed to you as parameters. (No side-effects.) Many methods automatically fall into this category, in which case you don't have to worry about concurrency.
If your method cannot be made threadsafe, you need to handle concurrent calls somehow. synchronized blocks are the most often used constructs but in some cases, a volatile field or using Atomic* classes will suffice. But this subject is way too heavy to be covered in a single answer, so I suggest you read the concurrency tutorial.