Will Multiple Threads cause Concurrency issue with static methods? - java

I have a Thread scenerio , in which 3 classes are MainThread.java,NormalWorkerClass1.java,NormalWorkerClass2.java
1 class:
class MainThread implements Runnable
{
private Thread thread = null;
//private variables
..
..
//default Constructor
public MainThread(){}
public MainThread(int val){
this.val=val;
}
public void start() {
thread = new Thread(this,"rootthread");
thread.start();
}
#Override
public void run() {
NormalWorkerClass1 instance1=NormalWorkerClass1.getInstance(); // Normal class
NormalWorkerClass2 instance2=NormalWorkerClass2.getInstance(); // for other working
try
{
while(true)
{
boolean retval=proccessSomething();
if(retval)
{
instance1.doMainProcess(arg..);
}
else
{
instance2.doMainProcess(arg..);
}
}
}
}
2 class:
class NormalWorkerClass1
{
private ...
private variables
public static NormalWorkerClass1 getInstance() {
return new NormalWorkerClass1();
}
public void doMainProcess(arg..)
{
Files processing()
// same common methods in NormalWorkerClass2
UtilityAccess ad=UtilityAccess.getInstance();
ad.Web Service part()
ad.dB part()
ad.Mail sending()
}
}
3 class:
class NormalWorkerClass2
{
private ...
private variables
public static NormalWorkerClass2 getInstance() {
return new NormalWorkerClass2();
}
public void doMainProcess(arg..)
{
Files processing()
// same common methods in NormalWorkerClass1
UtilityAccess ad=UtilityAccess.getInstance();
ad.Web Service part()
ad.dB part()
ad.Mail sending()
}
}
These are 3 classes.
My doubts are:
1 )In a multi threading Environment , i.e. if both class 2 and class 3 accessed at same time , whether
2 and 3 class cause any concurrency issue, because both are using some common methods and classes?
There is no Synchronisation part in this.
The web service part consists of another thread part.
2) What will happen when multiple thread access this,
NormalWorkerClass1 instance1=NormalWorkerClass1.getInstance(); // Normal class
NormalWorkerClass2 instance2=NormalWorkerClass2.getInstance(); // for other working
because its getInstance() method is a static method ,
multiple threads will share NormalWorkerClass1 and NormalWorkerClass2 class object values ?
5)Both classes NormalWorkerClass1 and NormalWorkerClass2 calls same common methods.. for e.g.. web service part.. if a thread1 enters into web service part and takes some time to complete ..on that particular moment another thread2 came to use web service part..this might cause any problem in total execution . same case with mail part also..will cause any issue in object clashing. I know each thread has its own stack for execution and have copies of variables
4) Can this Code cause any performance bottleneck? If yes ,How can I improve this code for multi threading and performance improving environment. ?
as i am new to this threading concurrency part..

Where concurrency causes problems is when multiple threads access shared state, your example doesn't have any shared state, it just shows static methods returning new instances of things. If you add static class variables that are accessed concurrently then you will have to worry about thread-safety issues with threads overwriting each others' work or with changes not being visible to other threads.
Calling methods doesn't in itself introduce concurrency problems, accessing and changing the contents of instance and class variables is what causes problems.

Nathan's Hughes answer is correct. I would add that there may be a concurrency problem if your run() method touches any instance variables of the MainThread class.
And one more thing - maybe obvious, maybe not: concurrency is about threads, not classes. Both NormalWorkerClass1 and NormalWorkerClass2 cannot conflict with each other when they are called from the same thread.

Related

How does multithreading method invocation work

I am using java.
I have an instance a of class A which has a public method foo() running and 2 other threads - threadB and threadC, all running at the same time.
here's class A
public class A {
int val = 0
public void foo(int incValue) {
a += incValue;
}
public static void main (String arg[]) {
MyThread a = new MyThread(this);
new Thread(a).start();
MyThread b = new MyThread(this);
new Thread(b).start();
}
}
here's the thread definition for threadB and threadC:
public class MyThread implements Runnable {
A main = null;
public MyThread(A main) {
this.main = main;
}
public callFoo(int incValue) {
main.foo(incValue);
}
#Override
public void run() {
//valToInc can be a value from a GUI form.
callFoo(valToInc);
}
}
If in threadB invokes callFoo(1) and threadC invokes callFoo(3) at the same time, then:
- Which thread will be able to call the method first?
- What is the result of the val in main class after both executions?
- Will the execution of the method for each thread happen concurrently or one after another?
There is absolutely no difference in how the JVM will invoke two methods "in parallel".
In other words: if you want to know what happens when a method is called, you can look here.
When a method is called "twice" in parallel, then that whole thing ... just happens twice!
Things become interesting when that method is making updates on that class, or in other objects! (like changing a field of your object, or appending a value to a list, ... )
You see, the real complexity of multi-threading is not about running some code in parallel. The real issue is what happens to "shared data".
If you find my answer to general; sorry - that is probably the best you can expect for such a generic question.
If [] threadB invokes callFoo(1) and threadC invokes callFoo(3) at the same time, then: - Which thread will be able to call the method first?
Threads run independently of each other. If there is no synchronization (there's none in your example), then any number of threads can be in calls to the same method at the same time.
Whenever a thread calls a method, it creates an activation record to hold all of the local variables and parameters of that method, and when several threads call the same method at the same time, each thread gets its own activation record. The threads can neither communicate with one another through the args and locals, nor can they interfere with one another's use of the args and locals.
They can, of course communicate and interfere with each other through any shared objects, including objects that may be referenced by the args or the locals.

How can I synchronize the class so that I can use from UI thread and background threads?

I have a utility class as follows:
public class MetaUtility {
private static final SparseArray<MetaInfo> metaInfo = new SparseArray<>();
public static void flush() {
metaInfo.clear();
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
metaInfo.append(key, info);
}
public static MetaInfo getMeta(int key) {
return metaInfo.get(key);
}
}
This class is very simple and I wanted to have a "central" container to be used across classes/activities.
The issue is threading.
Right now it is populated (i.e the addMeta is called) only in 1 place in the code (not in the UI thread) and that is not going to change.
The getter is accessed by UI thread and in some cases by background threads.
Carefully reviewing the code I don't think that I would end up with the case that the background thread would add elements to the sparse array while some other thread would try to access it.
But this is very tricky for someone to know unless he knew the code very well.
My question is, how could I design my class so that I can safely use it from all threads including UI thread?
I can't just add a synchronized or make it block because that would block the UI thread. What can I do?
You should just synchronize on your object, because what your class is right now is just a wrapper class around a SparseArray. If there are thread level blocking issues, they would be from misuse of this object (well, I guess class considering it only exposes public static methods) in some other part of your project.
First shoot can be with synchronized.
#Jim What about the thread scheduling latency?
Android scheduler is based on Linux and it is known as a completely fair scheduler (CFS). It is "fair" in the sense that it tries to balance the execution of tasks not only based on the priority of the thread but also by tracking the amount of execution time that has been given to a thread.
If you'll see "Skipped xx frames! The application may be doing too much work on its main thread", then need some optimisations.
If you have uncontended lock you should not be afraid of using synchronized. In this case lock should be thin, which means that it would not pass blocked thread to OS scheduler, but would try to acquire lock again a few instructions after. But if you still would want to write non-blocking implementation, then you could use AtomicReference for holding the SparseArray<MetaInfo> array and update it with CAS.
The code might be smth like this:
static AtomicReference<SparseArray<MetaInfo>> atomicReference = new AtomicReference<>();
public static void flush() {
atomicReference.set(new SparseArray<MetaInfo>);
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
do {
SparseArray<MetaInfo> current = atomicReference.get();
SparseArray<MetaInfo> newArray = new SparseArray<MetaInfo>(current);
// plus add a new info
} while (!atomicReference.compareAndSet(current, newArray));
}
public static MetaInfo getMeta(int key) {
return atomicReference.get().get(key);
}

Threads: Busy Waiting - Empty While-Loop [duplicate]

This question already has answers here:
Is this starvation?
(2 answers)
Closed 9 years ago.
During our lessons in the university, we learned about Threads and used the "Busy Waiting" method for an example of a Car waiting at a TrafficLight. For this task we build three classes:
TrafficLight (implements Runnable)
Car (implements Runnable)
Main
In our Main class we start two Threads, one of Car, and one of TrafficLight. The Car has the boolean attribute hasToWait. The run() method in this class works the way, that it works through a while loop as long as hasToWait == true. To change this, we have the notifyCar() method in the Car class, which is used by the TrafficLight. The run() method in TrafficLight runs through a Thread.sleep() to simulate a certain time of waiting.
Everything works fine at my Prof's but eventually I have serious problems with it. As long as the while loop in the Car class is empty. When I put in a System.out.println() - which is not empty, it works. But if the Syso is empty, the result is no displaying of the Text of the Run method.
Also it's working when the Thread.sleep() in TrafficLight is 0. Than it works with an empty while loop.
Here is my code:
Car.java:
package trafficlight;
public class Car implements Runnable {
private boolean hasToWait = true;
public void run() {
this.crossTrafficLight();
}
public void crossTrafficLight() {
while(hasToWait){ for(int i = 0; i<20; i++){System.out.println("123");}} // Busy waiting
System.out.println("Auto fährt über Ampel");
}
public void notifyCar() {
this.hasToWait = false;
System.out.println("Test");
}
}
TrafficLight.java:
package trafficlight;
public class TrafficLight implements Runnable {
private Car car;
public TrafficLight(Car car) {
this.car = car;
}
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.car.notifyCar();
}
}
Main.java:
package trafficlight;
public class Main {
public static void main(String[] args){
Car car = new Car();
TrafficLight tl = new TrafficLight(car);
new Thread(car).start();
new Thread(tl).start();
}
}
Where is the problem? Why does it work at my profs but not at my computer? I got the code 1:1 in my Eclipse Juno, using JRE 1.7
In addition to everything said in this other answer (just substitute your hasToWait for finished in that answer), the reason why the code starts working when you add a println is as follows:
println is a synchronized method;
you call it in both threads;
this creates a happens-before relationship between the two threads;
therefore the write to the boolean flag becomes visible to the child thread.
You could say that it starts working mostly by accident: you are piggybacking on the synchronization going on in println.
The real problem with your code is the instance field hasToWait. This field is being used by two threads. The car thread reads the value, and the traffic light thread updates the value after some time.
The access to this field must be synchronized in some way.
There are two ways to do this:
Use the synchronized keyword. Either by using a synchronized block at all places, where it is read or written, or - better - write a synchronized getter and a synchronized setter, then use the getter and the setter inside the Car class.
Use the volatile keyword. Just declare your field as volatile. This keyword exists for exactly that case. More information on volatile can be found in Oracle's Java Tutorials.
After reading the article about atomic access (see link above), it should be clear that option 2 (declaring volatile) is the far better option - for this use case.
Now to the difference you see between your computer and your professor's computer: As long as you are using a single-core-processor, you will see updates on an instance field in other threads as though they were synchronized, because the CPU does not have to synchronize these values in the other cores' cache areas. If you use a multi-core-processor, then the JVM is able to run threads on several cores. That means, that these cores have to synchronize values, and the volatile mechanism is exactly designed for that.

Regarding same Runnable reference on Multiple Treads [duplicate]

This question already has answers here:
Initializing two threads with the same instance of a runnable
(4 answers)
Passing single runnable object to multiple thread constructors [duplicate]
(2 answers)
Closed 9 years ago.
When we call start() on a Thread by passing a Runnable object as argument, can we pass the same Runnable reference to start multiple threads?
public class MyMain {
public static void main(String[] args) {
MyRunnableImpl impl = new MyRunnableImpl();
new Thread(impl).start();
new Thread(impl).start();
}
}
Yes, you can do this when your Runnable is implemented accordingly.
But you have to be careful your Runnable implementation does not contain a mutable state. You can control this in your own implementations, but the Runnable contract does not specify.
// can be used for multiple Threads
class StatelessRunnable {
public void run() {
doSomething();
}
}
// may go bang on the second execution -> use two instances
class StatefulRunnable {
volatile boolean canRun = true;
public void run() {
if(!canRun) throw new IllegalStateException();
canRun = false;
}
}
In the above sample you see that you can use StatelessRunnable for as many threads as you like. In fact you could even make it a singleton. StatefulRunnable in contrast can be run only once per instance.
Shared State
Reading Jon's answer I realised there may be scenarios where you actually want to share a state of two Runnable instances. Of course a stateful Runnable instance is not always bound to fail with multiple threads, but this is much more trickier to get right than a stateless one.
// willingly share state over threads
class WillinglyStatefulRunnable {
final BlockingQueue<Object> sharedObjects = new BlockingQueue<Object>();
public void run() {
sharedObjects.offer(new Object());
}
}
The above example shows how you could work on a single collection sharedObjects with multiple threads.
Literature Sidenote:
Item 15 in Joshau Bloch's Effective Java says Minimize Mutabilty. This chapter - in case you have access to the book - addresses similar points in a much more general context. Shortly summarised he states that immutable objects make it easier to reuse instances and reduce the potential of illegal states.

Any gotchas using static inner classes in a multi threaded environment?

This is my first foray into multi threaded land and I'm currently implementing a solution using the Java concurrency library. The code essentially takes in a number of service requests, submits all the requests asynchronously and returns a map of responses when all services have completed. My code looks something like this:
public OuterClass {
public IResponseMap sendAsynchronousRequests(IRequest... dataList) {
List<RepositoryFutureTask<IRequest>> futures = new ArrayList<RepositoryFutureTask<IRequest>>();
//create one future for each request in the list
for (final IRequest request : dataList) {
RepositoryFutureTask<IRequest> future = new RepositoryFutureTask<IRequest>(request.getId(), new Callable<IRequest>() {
public IResponse call() {
return request.getService().callService(request.getRequestData());
}
});
futures.add(future);
}
//Submit each future for execution
for(Future future:futures) {
//Singleton ReqeustExecutorService maintains a pool of threads via
// java.util.concurrent.ExecutorService
RequestExecutorService.execute(future);
}
//Block processing until all requests have finished and add responses to map
//based on id as they finish
IResponseMap responseMap = new ResponseMap();
for(RepositoryFutureTask future:futures) {
responseMap.put(future.getId(), future.get());
}
return responseMap;
}
static class RepositoryFutureTask extends FutureTask<IResponse> {
private String id;
public RepositoryFutureTask(String theId, Callable<IResponse> callable) {
super(callable);
id = theId;
}
//standard getter for id omitted for conciseness
}
}
I'm primarily interested if my static inner class solution will create any issues in a multi threaded enviroment, but would also be interested in any other comments on the above solution. Note that there's a chance the code above isn't perfect as its still somewhat pseudo code and I've generified it a lot. Error handling has also been removed. Thanks in advance.
No, static inner classes are loaded in a manner equivalent to a top level classes. See 8.5.2 of the JLS -- http://java.sun.com/docs/books/jls/third_edition/html/classes.html
If you have a synchronized static method in a static nested class, it will be a lock on a different object to the same in the outer class. I would really recommend the synchronized modifier on any method, and particularly on a static method.
More a problem with anonymous inner classes, locks on this will be different. Even if you write synchronized (this) { it really isn't that obvious. I have seen it done a few times.
Theoretically I guess you could potentially run into trouble if the nested class static initialiser ran in parallel to the outer nester class static initialiser. Technically this is the same as running static intiailsers in two outer classes, but you are more likely to have cyclic dependencies with nested classes.
No issues with using static inner class. The only issues is that private String id; is not final. Make it final and you'll be alright with thread-safety ;-)

Categories