Folks,
I know this question has been asked before here, though indirectly. But it didn't answer my doubt.
Question : Is it legal to call the start method twice on the same Thread?
From the spec,
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
I agree. But my code doesn't throw a IllegalThreadStateException which it is expected to throw on execution of following program.
public class Tester extends Thread {
public void run() {
System.out.print("run");
}
public static void main(String[] args) {
Tester thread = new Tester();
new Thread(thread).start();
new Thread(thread).start();
}
}
Q.1) I ran the above code in Eclipse. Here, since I am trying to start a new thread on the same instance, a IllegalThreadStateException is expected to be thrown. But it doesn't.
Why ?
Q.2) If at all we did start a new thread on the same instance, what harm it would do ?
Any help would be greatly appreciated !
You are NOT calling start() on the same instance. Everytime you use new you are creating a distinct instance. Hence no problem calling start().
If you did this:
Thread t = new Thread(thread);
t.start();
t.start();
Then you may have a problem.
Firstly, you are invoking on two different thread objects ie:
new Thread(thread).start();
new Thread(thread).start();
you are calling start method on two different instances. for which reason you are not getting the exception.
try with following to get the exception
thread.start();
thread.start();
For your second question. you can get the answer here : Why can't we call the start method twice on a same instance of the Thread object?
which is fortunately asked by me :)
Can java thread invoke start more than once ?
You can involve start() as often as you like. However you will get an IllegalThreadStateException if you call it more than once on the same Thread.
Q.1) I ran the above code in Eclipse. Here, since I am trying to start a new thread on the same instance, a IllegalThreadStateException is expected to be thrown. But it doesn't.
Thats because you created three different threads. One is the Tester and two wrap the Tester.
Q.2) If at all we did start a new thread on the same instance, what harm it would do ?
Other than create confusion, none. You shouldn't do this. Instead the Tester should implement Runnable.
Q.1) I ran the above code in Eclipse. Here, since I am trying to start a new thread on the same instance, a IllegalThreadStateException is expected to be thrown. But it doesn't.
You are not caling start() on same instance.
new Thread(thread).start();
the above statement is same as
new Thread((Runnable)thread).start();
As most of all answers covered Q1, Here i would like to concentrate on Q2 which is " If at all we did start a new thread on the same instance, what harm it would do ?"
first point to consider is when do you want want to call the thread start method second time,is it when the first thread is executing(case:1) or else after the execution of first thread is done(case 2)
case1 : To identify the thread which is started and executing the only way we have is thread object which is used for creation, so IF there was a chance to call the start() method second time there would be for suppose other thread getting created and it executes, but if we want to change/manipulate a particular thread of the multiple threads which are executed on a particular instance how would we identify them individually,so it would be totally impossible and so to identify a running thread uniquely and work on it java didn't allow to call start() method multiple times .
case 2:why didn't java allow us to call start() method multiple times if already running thread is finished?
in java once the scope of the object is ended it need to be garbage collected,so in case of thread objects also this happen,but if there is a facility to call start method multiple times the java env should not allow GC to takes place on thread object thinking that there may be a second time to use this thread object and this thread object will forever be in heap(or some place) without getting GC.
so considering above two reasons they might have made restrictions on calling start() method on a thread object only once.
And here we see why the Executors make so much sense.
Typical idiomatic Java would say that you shouldn't run your own threads much at all; create an executor service, and let it manage the threads. You just create Runnable instances and pass those to the executor service; you can call Runnable's run() method as often as you like, whenever and wherever it makes sense to do so, and you don't have to concern yourself with Thread management at that point.
Extending Thread is also a one-shot deal; extending superclasses in Java is expensive (since you get ONE superclass, that's it). However, you can extend as many interfaces as you like, so Runnable gives you a more powerful object hierarchy as well.
Related
This question already has an answer here:
NetworkOnmainThreadException android+Rxjava
(1 answer)
Closed 10 months ago.
Does this line:
ClientThread.ClientSocket.getInputStream().read()
takes ClientThread's method and executes it on MainUI thread, or does it tell ClientThread to execute it?
It results in MainThreadNetworking Exception so I believe it's the first option, sadly. If so, how can I execute that method in the ClientThread instead?
There is no way to tell another thread to execute something. So, no, the above simply runs it in your thread. Note, there's the concept 'Thread -a thing that runs on an OS core' and 'java.lang.Thread - an object that represents that concept'. They are not quite identical. I'll use j.l.Thread to indicate the Thread object and just thread for the OS concept. j.l.Thread is just an object, it's not particularly magical. Just interacting with a j.l.Thread instance is just.. interacting with an object. It doesn't convey magical 'anything you do with this object somehow runs in a separate thread' powers.
There are only only 2 ways to tell another thread (OS-level or j.l.Thread) to execute something, i.e., only 2 ways to use j.l.Thread to actually run stuff in separate threads:
When creating a j.l.Thread, you pass along the 'run()' code (either passing a Runnable, or extending Thread and supplying a run() method). When some thread runs the code thatThreadObject.start() (note: not run!) - then that starts an actual thread, and that newly created thread will, after initializing, begin by executing the code in that run() method of the j.l.Thread object.
By programming it. In other words, perhaps some thread looks like this:
private class Runner extends Thread {
private final ArrayBlockingQueue <Runnable> queue = new ArrayBlockingQueue<>(1000);
public void offer(Runnable r) {
queue.add(r);
}
#Override public void run() {
while (true) {
Runnable r = queue.take();
r.run();
}
}
}
Then, imagine some code is running in a thread (not the thread represented by the j.l.Thread instance made from the above code), and calls thatThreadObj.offer(() -> System.out.println("Hello!");...
then eventually the thread represented by that j.l.Thread will run it. Because you programmed it to do this.
If you want something like that, note that the java.util.concurrent package has implementations of this concept (ExecutorPool and friends). Don't write it yourself.
My questions are:
Does a Java program, by default, cause creation of only 1 thread?
If yes, and if we create a multi threaded program, when do multiple threads access the same code of a Java object?
For example I have a Java program with 2 methods - add() and sub(). In what scenario will 2 or more threads run the 'add()' method?
Isn't code always thread safe, as multiple threads will access different sections of code?
If not, please show an example program where thread safety is a concern.
Don't think of "sections of code", think of where the data lives and how many threads are accessing that actual data.
Local variables live on the stack of the thread they are being used in and are thread safe since they are different data "containers" per thread.
Any data that lives on the heap, like instance or static fields, are not inherently thread-safe because if more than one thread accesses that data then they might have contention.
We could get more complicated and talk about where the data really is but this basic explanation should give you a good idea of what's going on.
The below code gives an example of an instance that is shared by two threads, in this case both threads are accessing the same array list, which is pointing to the same array data containers in the heap. Run it a couple times and you'll eventually see a failure. If you comment out one of the threads it will work correctly every time, counting down from 99.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
new Thread(r).start();
new Thread(r).start();
}
public static class MyRunnable implements Runnable {
// imagine this list living out in the heap and both threads messing with it
// this is really just a reference, but the actual data is in the heap
private List<Integer> list = new ArrayList<>();
{ for (int i = 0; i < 100; i++) list.add(i); }
#Override public void run() {
while (list.size() > 0) System.out.println(list.remove(list.size() - 1));
}
}
}
1) Does a Java program, by default, cause creation of only 1 thread?
Really depends on what your code is doing. A simple System.out.println() call might probably just create one thread. But as soon as you for example raise a Swing GUI window, at least one other thread will be around (the "event dispatcher thread" that reacts to user input and takes care of UI updates).
2) If yes, and if we create a multi threaded program, when do multiple threads access the same code of a Java object?
Misconception on your end. Objects do not have code. Basically, a thread will run a specific method; either its own run() method, or some other method made available to it. And then the thread just executes that method, and any other method call that is triggered from that initial method.
And of course, while running that code, that thread might create other objects, or manipulate the status of already existing objects. When each thread only touches a different set of objects, then no problems arise. But as soon as more than one thread deals with the same object state, proper precaution is required (to avoid indeterministic behavior).
Your question suggests that you might not fully understand what "thread" means.
When we learned to program, they taught us that a computer program is a sequence of instructions, and they taught us that the computer executes those instructions one-by-one, starting from some well-defined entry point (e.g., the main() routine).
OK, but when we talk about multi-threaded programs, it no longer is sufficient to say that "the computer" executes our code. Now we say that threads execute our code. Each thread has its own idea of where it is in your program, and if two or more threads happen to be executing in the same function at the same time, then each of them has its own private copy of the function's arguments and local variables.
So, You asked:
Does a Java program, by default, cause creation of only 1 thread?
A Java program always starts with one thread executing your code, and usually several other threads executing JVM code. You don't normally need to be aware of the JVM threads. The one thread that executes your code starts its work at the beginning of your main() routine.
Programmers often call that initial thread the "main thread." Probably they call it that because it calls main(), but be careful! The name can be misleading: The JVM doesn't treat the "main thread" any differently from any other thread in a multi-threaded Java program.
if we create a multi threaded program, when do multiple threads access the same code of a Java object?
Threads only do what your program tells them to do. If you write code for two different threads to call the same function, then that's what they will do. But, let's break that question down a bit...
...First of all, how do we create a multi-threaded program?
A program becomes multi-threaded when your code tells it to become multi-threaded. In one simple case, it looks like this:
class MyRunnable implements Runnable {
public void run() {
DoSomeUsefulThing();
DoSomeOtherThing();
}
}
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
...
Java creates a new thread when some other thread in your program calls t.start(). (NOTE! The Thread instance, t, is not the thread. It is only a handle that your program can use to start the thread and inquire about its thread's state and control it.)
When the new thread starts executing program instructions, it will start by calling r.run(). As you can see, the body of r.run() will cause the new thread to DoSomeUsefulThing() and then DoSomeOtherThing() before r.run() returns.
When r.run() returns, the thread is finished (a.k.a., "terminated", a.k.a., "dead").
So,
when do multiple threads access the same code of a Java object?
When your code makes them do it. Let's add a line to the example above:
...
Thread t = new Thread(r);
t.start();
DoSomeUsefulThing();
...
Note that the main thread did not stop after starting the new thread. It goes on to execute whatever came after the t.start() call. In this case, the next thing it does is to call DoSomeUsefulThing(). But that's the same as what the program told the new thread to do! If DoSomeUsefulThing() takes any significant time to complete, then both threads will be doing it at the same time... because that's what the program told them to do.
please show an example program where thread safety is a concern
I just did.
Think about what DoSomeUsefulThing() might be doing. If it's doing something useful, then it almost certainly is doing something to some data somewhere. But, I didn't tell it what data to operate on, so chances are, both threads are doing something to the same data at the same time.
That has a lot of potential to not turn out well.
One way to fix that is to tell the function what data to work on.
class MyDataClass { ... }
Class MyRunnable implements Runnable {
private MyDataClass data;
public MyRunnable(MyDataClass data) {
this.data = data;
}
public void run() {
DoSomeUsefulThingWITH(data);
DoSomeOtherThingWITH(data);
}
}
MyDataClass dat_a = new MyDataClass(...);
MyDataClass dat_b = new MyDataClass(...);
MyRunnable r = new MyRunnable(dat_a);
Thread t = new Thread(r);
t.start();
DoSomeUsefulThingWITH(dat_b);
There! Now the two threads are doing the same thing, but they are doing it to different data.
But what if you want them to operate on the same data?
That's a topic for a different question. Google for "mutual exclusion" to get started.
Depends on the implementation. Only one thread (the "main thread") will invoke the public static void main(String[]) method, but that doesn't mean other threads weren't started for other tasks.
A thread will access the "same code" if you program it to do so. I'm not sure what your idea of "section of code" is or where the idea that two threads will never access the same "section" at the same time comes from, but it's quite trivial to create thread-unsafe code.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws InterruptedException {
List<Object> list = new ArrayList<>();
Runnable action = () -> {
while (true) {
list.add(new Object());
}
};
Thread thread1 = new Thread(action, "tread-1");
thread1.setDaemon(true); // don't keep JVM alive
Thread thread2 = new Thread(action, "thread-2");
thread2.setDaemon(true); // don't keep JVM alive
thread1.start();
thread2.start();
Thread.sleep(1_000L);
}
}
An ArrayList is not thread-safe. The above code has two threads constantly trying to add a new Object to the same ArrayList for approximately one second. It's not guaranteed, but if you run that code you might see an ArrayIndexOutOfBoundsException or something similar. Regardless of any exceptions being thrown, the state of the ArrayList is in danger of being corrupted. This is because state is updated by multiple threads with no synchronization.
I'm trying to learn threads in Java. I've followed two different tutorials, but I feel like I'm not really getting the concept. As I understand it, when you create threads, you use the Thread class, and then embedding your own object within the thread. I can do that, but I can't figure out how to access the instance variables within the "embedded" object.
Suppose as a learning exercise, I wanted to create three threads which would go off and do work individually of one another. I could define this object to "drive" the threads:
public class StoogeObject implements Runnable {
String name;
int data;
public StoogeObject(String name, int data){
this.name=name;
this.data=data;
}
#Override
public void run() {
System.out.println("Thread "+this.name+" has this data: "+this.data);
// Do useful work here
System.out.println("Thread "+this.name+" is exiting...");
}
public String getName(){
return this.name;
}
}
Then, in a driver program, I would launch my threads:
public class driver {
public static void main(String[] args){
Thread stooge1 = new Thread(new StoogeObject("Larry", 123));
Thread stooge2 = new Thread(new StoogeObject("Curly", 456));
Thread stooge3 = new Thread(new StoogeObject("Moe", 789));
stooge1.start();
stooge2.start();
stooge3.start();
if(stooge1.isAlive())
System.out.println("From main(): "+stooge1.getName());
}
}
Output is:
From main(): Thread-0
Thread Larry has this data: 123
Thread Curly has this data: 456
Thread Moe has this data: 789
Thread Larry is exiting...
Thread Curly is exiting...
Thread Moe is exiting...
I was surprised when the stooge1.getName() line in main() produced "Thread-0", not "Larry". I was expecting the getName() method I wrote in stoogeObject.java to override and return the instance variable String name in this instance. Instead, I'm getting the name of the Thread, not the StoogeObject.
So... The stooge1 thread has a StoogeObject within it, but I don't know how to access its instance variables. More significantly, this example makes me wonder if I'm missing the point of threads. If I want my Larry, Curly, & Moe objects to go off and do productive work AND keep their own instance variables, is using threads the wrong way to go here? Should I start over, making these objects into processes?
I can't figure out how to access the instance variables within the "embedded" object.
You access them in exactly the same way that you would access the instance variables of any other object.
The "embedded" object, FYI, is called the thread's target or the thread's delegate.
There is nothing special about the target of a Thread. It's just an object.
I was surprised when the stooge1.getName() line in main() produced "Thread-0", not "Larry". I was expecting ... Instead, I'm getting the name of the Thread, not the StoogeObject.
That's because the Thread object and the StoogeObject are different objects.
this example makes me wonder if I'm missing the point of threads.
There are two different ways that threads can be used in a program. The first (which is what people think of more often than not) is that threads are how a Java program can make use of more than one CPU if your platform has more than one CPU. (Virtually all modern servers and workstations have more than one these days, and it's getting to where a lot of cell phones and tablets have more than one as well.) If your platform has, say eight CPUs, then up to eight of your threads may be able to run simultaneously if that many of them are "ready to run."
The second way to use threads in a program is to wait for things. For example, if your program is a server that has to waits for input from each of N clients, and respond to it; you can structure it as N threads that each just listen to and respond to one client. That often makes the code easier to understand. (Just like, it's easier to juggle one ball than it is to juggle N balls).
is using threads the wrong way to go here? Should I start over, making these objects into processes?
Threads can be much more tightly coupled than processes because the threads of a single program all share the same virtual address space (i.e., in a Java program, they all share the same heap). Communication between threads usually is one or two orders of magnitude faster than communication between different processes on the same machine.
If you need fine-grained communication between them, then they definitely should be threads. A good rule of thumb is that, an application should never spawn a new process unless there is a really good reason why it should not be just another thread.
If you want to access the runnable object that you pass to the thread, you need to keep a reference to it.
Here is an example:
stoogeObject obj = new stoogeObject("Larry", 123);
Thread stooge1 = new Thread(obj);
stooge1.start();
System.out.println(obj.getName());
This will print Larry.
Keep in mind that if the name variable from the stoogeObject instance is changed during the thread's runtime, you'll have to wait for that thread to finish (or finish changing the variable) in order to get the correct value.
You can do that by using join().
stoogeObject obj = new stoogeObject("Larry", 123);
Thread stooge1 = new Thread(obj);
stooge1.start();
stooge1.join();
System.out.println(obj.getName());
Here the System.out.println(obj.getName()) statement is executed only after the thread is done.
I was surprised when the stooge1.getName() line in main() produced "Thread-0", not "Larry". I was expecting the getName() method I wrote in stoogeObject.java to override and return the instance variable String name in this instance. Instead, I'm getting the name of the Thread, not the StoogeObject.
How is this surprising? You never set the thread's name, then you call stooge1.getName(), and stooge1 is the Thread, and you're getting precisely what you asked for: "the name of the Thread".
The only thing the Thread knows about the Runnable that you pass it is that it has a run() method, it doesn't know or care about any other things you've added to your Runnable implementation.
If you want to set the thread's name, either use the Thread constructor that takes a name:
Thread stooge1 = new Thread(new StoogeObject(...), "Thread's Name");
Or set its name later:
stooge1.setName("Thread's Name");
So... The stooge1 thread has a StoogeObject within it, but I don't know how to access its instance variables.
It's up to you to store and manage your StoogeObjects, and Titus' answer covers this nicely. I just wanted to add a bit on top of that to answer your thread name related question.
As a side note: Once you wrap your head around the fundamentals, check out the official high-level concurrency tutorial, particularly the section on "executors". The Java API provides a few really convenient high-level constructs for concurrency that you might find useful in certain situations.
I have a class which basically does the same series of steps twice. Sounds like a perfect example of where to multithread your program. My question is though if I can do this with only two threads. Here is the general jist of things
Tester implements Runnable{
Thread obj1Thread, obj2Thread;
MyObj obj1, obj2;
String obj1Results, obj2Results;
void runTests(){
obj1Thread = new Thread(this, "ob1 thread");
obj2Thread = new Thread(this, "ob2 thread");
obj1.start();//builds up obj1
obj2.start();//builds up obj2
if(obj1 and obj2 are finished building){
System.out.println(obj1);
System.out.println(obj2);
}
obj1Thread.startSecondPhase()//runs a separate function that tests obj1 vs ob2. Essentially test(ob1, ob2)
obj2Thread.startSecondPhase()//runs a separate function that tests obj2 vs ob1. Essentially test(ob2, ob1)
if(obj1 and obj2 are finished testing){
System.out.println(obj1Results);
System.out.println(obj2Results);
}
}
}
I have gotten the first part - building up the objects - working. My questions are now -
How can I get the main thread to wait for the two threads to finish their first part? Perhaps the main would do a wait on both objects and then after the threads notifyAll they do a wait on the main thread? But then how do the threads get a hold of the main thread? Perhaps with this?
How can I have this 'second phase' of the run function without making a new class with a new thread and a new specific run function? I dont want to have to make a new class and everything for every little task.
To clarify the sequence of events I want specifically is -
Main thread initializes and starts two threads
Both threads simultaneously build their respective objects
When both threads finish building they pause. Then main thread prints the objects out in order.
After main thread is done, the two threads continue their code to a testing phase simultaneously
When the threads are done the main thread prints the results out. Could probably use a join() here
Edit: Also, how can I tell the specific threads which objects I want them to work on? Right now Im doing it in a kinda hacky way (i'm working off the thread name).
I would use higher-level abstractions: use an execute and ExecutorService.invokeAll(Collection<? extends Callable<T>> tasks), which returns a list of Future.
Your main thread can
dispatch two tasks,
obtain two futures,
print the results, then
dispatch two more tasks
The executor service and futures will handle all the concurrency under the hood.
EDIT:
I see your comment:
A special Runnable class just to implement basically one line of code?
Perhaps I'm being too idealistic but that feels wrong to me.
You typically use ananymous inner classes in such case:
Future future = executorService.submit(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
Nothing wrong with that. When Java has lambda it will become even shorter.
Future future = executorService.submit(() -> {System.out.println("Asynchronous task");});
I'm learning threads yet, but don't know much things.
I see that I need implement the Runnable interface and create various instances of the same class to each thread execute each one. It's correct?
If is correct, I need to create another class to contains the variables that will be accessed/shared by all threads?
EDIT: I need maintain some variables to coordinate the thread work, otherwise they will execute the same work. This will be one variable shared by all threads.
EDIT 2: this questions is related to this: How I make result of SQL querys with LIMIT different in each query? . I will need maintain the quantity of threads that have done a query to database to set the OFFSET parameter.
Each thread needs an instance of a Runnable to do its work, yes. In some cases the threads could share the same instance, but only if there is no state held within the instance that needs to differ between threads. Generally you will want different instances in each thread.
Threads should share as little state as possible to avoid problems, but if you do want to share state, in general you are right that you will need an instance or instances somewhere to hold that state.
Note that this shared state could also be held in class variables rather than instance variables.
There are many ways to solve this...this is really a question about Design Patterns.
Each thread could be provided via it's constructor an object or objects that describe its unique work.
Or you could provide the thread with a reference to a work queue from which they could query the next available task.
Or you could put a method in the class that implements Runnable that could be called by a master thread...
Many ways to skin this cat...I'm sure there are existing libraries for thread work distribution, configuration, etc.
Let's put all things on their places.
Statement new Thread(r) creates thread. But this thread still does not run. If you say"
Thread t = new Thread(r);
t.start();
you make thread to run, i.e. execute run() method of your runnable.
Other (equal) way to create and run thread is to inherit from class Thread and override default implementation of its run() method.
Now. If you have specific logic and you wish to run the same logic simultaneously in different threads you have to create different threads and execute their start() method.
If you prefer to implement Runnable interface and your logic does not require any parameters you even can create only one instance of your runnable implementation and run it into different threads.
public class MyLogic implements Runnable {
public void run() {
// do something.
}
}
//// ................
Runnable r = new MyLogic();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
Now this logic is running simultaniusly in 2 separate threads while we created only one instance of MyLogic.
If howerver your logic requires parameters you should create separate instances.
public class MyLogic implements Runnable {
private int p;
public MyLogic(int p) {
this.p = p;
}
public void run() {
// this logic uses value of p.
}
}
//// ................
Thread t1 = new Thread(new MyLogic(111));
Thread t2 = new Thread(new MyLogic(222));
t1.start();
t2.start();
These 2 threads run the same logic with different arguments (111 and 222).
BTW this example shows how to pass values to thread. To get information from it you should use similar method. Define member variable result. The variable will be initiated by method run(). Provide appropriate getter. Now you can pass result from thread to anyone that is interesting to do this.
Obviously described above are basics. I did not say anything about synchronization, thread pools, executors etc. But I hope this will help you to start. Then find some java thread tutorial and go through it. In couple of days you will be the world class specialist in java threads. :)
Happy threading.