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.
Related
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.
I have been working on writing a multi threaded java program. Before I progress I was thinking how best I can write the program.
I read the differences between runnable and thread and what we should use and what we should not. However I have a question. Is it good to follow the runnable implementation to thread even if the threads are not sharing data i.e the same runnable class object?
I would end up creating different runnable objects thus occupying memory.
Also another idea I have is to pool runnable objects and change the value they hold and assign it to a thread. Thereby having only a set of runnable objects and thus utilizing memory better.
Sample Code:
public class MrRunnable implements Runnable {
private String toFireUrl;
MrRunnable(String url){
}
#Override
public void run() {
// do some function here
}
}
public class Main {
public static void main(String[] args) {
// We will create 500 threads
for (int i = 0; i < 500; i++) {
Runnable task = new MrRunnable("some new url");
Thread worker = new Thread(task);
//start the thread
worker.start();
}
}
}
Here I am creating a new instance of runnable objects and my threads don't share data.
So is this way justified? Or is it better to create a pool of runnable objects and I let my threads manipulate their content and use it?
Each thread you start allocates a call stack, sized by default at 1 Megabyte. Each MrRunnable you create allocates... 24 bytes. Keeping things in perspective helps.
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.
I have a tree structure that I am trying to use a recursive method to add, get, or remove an item. I would like to be able to introduce a new thread for every child node that I find with an iterator. I currently pass the node into the recursive method when I call it. I would like to be able to start a thread and tell that thread to call that method. How would I do something similar to saying new thread, thread.callMethod()? I need to have a Runnable interface and a run method apparently? However this seems to complicate things much more than necessary (I already have method names). Does anyone know a good way to do this using run(..), or does anyone know a better way to do this without using run(..). Thanks.
Thank you for your answers. I had been thinking that I need to somehoe get a new instance of a node running on a new thread, but that is not the case. The node just occupies space in memory and the thread is reference to the method code that is executed on the instance living in memory (my CS 302 TA is already disagreeing with me in my head). So.. I had been thinking about enums, but I was thinking that I might somehow need to have all my nodes running on separate threads during instantiation, or else, have the methods actually written in new classes that implement runnable.
In other words,
public class TreeMethods implements Runnable
{
...
run(.. node, .. params, .. enum)
{
switch(enum)
case(add)
{
myThreadInstanceMethod(node);
}
...
}
myThreadInstanceMethod(..) {..}
}
Thanks. I didn't know that I was asking this question, but you've just simplified my thread management design process greatly.
You can't do it without a Runnable or Callable object. The proper way to do what you want is to create a Runnable class that takes your object and calls the appropriate method on that object.
public class MyRunnable implements Runnable {
private MyObject obj;
public MyRunnable(MyObject obj) {
this.obj = obj;
}
public void run() {
obj.someMethod();
}
}
If you need to call one of a couple methods then you can use an enum for this. If you need to pass in arguments then you can add them to the constructor.
With threads, it's always recommended that you use the Executors class and the ExecutorService thread pools. This will limit the number of threads created by your recursive algorithm and keep the thread particulars hidden.
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
while (recursing) {
threadPool.submit(new MyRunnable(myObject));
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
...
You may need something like this:
Your runnable:
public class ComputeNode implements Runnable {
private Node node;
public ComputeNode(Node nodeToCompute) {
this.node = nodeToCompute;
}
#Override
public void run() {
computeOnNode(node);
}
}
How to start it:
Runnable compute = new ComputeNode(nodeToComputeOn);
Thread t = new Thread(comute);
t.start();
ComputeOnNode() is your own method written somewhere.
Is it bad programming to initialize two threads with the same instance of a runnable? What difference would it make to initialize with separate instances of a runnable, and does sharing memory locations at all for the same instance of a runnable have anything to do with performance?
public static void main(String[] args)throws Exception {
H h = new H();
H h2 = new H();
Thread j = new Thread(h);
j.setName("11");
Thread jj = new Thread(h);//instead of new H()
jj.setName("22");
j.start();
jj.start();
}
class H implements Runnable {
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName());
}
}
}
It's absolutely fine to do it so long as the code you're running is designed to support that. Not only will it save some memory by having a single instance instead of multiple instances, but if those threads are trying to communicate via shared data, then it may be absolutely required!
Admittedly communicating via shared state is where threading often gets tricky, so this needs to be done carefully, but from the point of view of the threading system itself, there's absolutely no problem in having two threads call the run method of a single Runnable instance.
Since H doesn't have any instance state, using multiple instances won't matter. You need to take care when the Runnable instances start storing state.
public class Main implements Runnable {
volatile int i;
public void run() {
for (i = 0; i < 100; i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
Main a = new Main();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start();
t2.start();
}
}
What gets printed? When you do need to share state between threads, it's a good idea to use the classes in java.util.concurrent. They were written primarily by an expert in multithreading (Doug Lea, author of Concurrent Programming in Java) and tested by many people. Save yourself some heartache. :)
Is it bad programming to initialize two threads with the same instance of a runnable?
Not specifically. However, if the Runnable instance has instance fields, then you'll need to make sure that all access to the fields by the thread is properly synchronized, and this will make the code more complicated.
What difference would it make to initialize with separate instances of a runnable, and does sharing memory locations at all for the same instance of a runnable have anything to do with performance?
The memory saved by sharing a Runnable instance between multiple threads is insignificant ... unless the Runnable holds a significant amount of instance data. (And if it does, the chances are that this will make the instance non-shareable.)
Your H class is an example where sharing instances is safe, but pointless since the memory saving is insignificant. (A Runnable object with no instance fields occupies roughly 8 to 16 bytes, depending on the platform.)
To make understand easily(based on the comment of Stephen), added the below program block about the impact of accessing the instance variable from a non-synchronized block with the same instance of Runnable displays the unexpected results.
public class SynchronizedInstanceMethod implements Runnable{
private int counter;
public SynchronizedInstanceMethod(int counterValue){
this.counter = counterValue;
}
private synchronized void displayMessage(){
System.out.println(" Display Message ");
}
private void modifyCounter(){
this.counter++;
System.out.println("Value -- "+ this.counter);
}
#Override
public void run() {
this.displayMessage();
this.modifyCounter();
}
public static void main(String[] args) {
SynchronizedInstanceMethod instance = new SynchronizedInstanceMethod(5);
new Thread(instance).start();
new Thread(instance).start();
}
}