I'm confused about what is the current thread during the execution of a multithreaded program.
public class CurrentThread {
public static void main(String[] args) {
// FROM HERE: will always be "main-thread" the current thread ?
CurrentThread currentThread = new CurrentThread();
currentThread.testCurrentThread();
// TO HERE
}
private void testCurrentThread() {
// some other threads starts...
AThread athread = new AThread();
athread.start();
// some other threads starts...
}
class AThread extends Thread {
public AThread() {
setName("thread-a");
}
public void run() {
// FROM HERE: will always be thread-a the current thread during finish the run method ?
// some process
// TO HERE...
}
}
}
Suppose that launches multiple threads before and after start the thread AThread:
When you are inside the main method, whenever you call Thread.currentThread() will be "main-thread"?
When you are inside the run method of AThread, whenever you call Thread.currentThread() will be "a-thread"?
Thanks in advance.
currentThread: Returns a reference to the currently executing thread
object.
So when you are in your main method, that is your main thread and when you are in run method of AThread, then that is your a-thread.
If I understand your question correctly, you are unclear about the distinction of "main thread" and "current thread". First, the main thread is the thread that defines the context of your application; when the main thread ends, the application is (supposed to) end as well.
"Current thread" can be relative; you can have any number of threads running simultaneously--that's the point of threads--but "current thread" can mean "the thread of execution we're talking about now", or it can mean the Thread object which you get a reference to by calling the static method, as previously mentioned--that means "this thread, the path of execution I'm a step of". If you call the currentThread() method in your main class or the thread in which your main class is running, you'll get a reference to the main thread--the thread controlling the lifecycle of the application (this is drastically oversimplified). If you call currentThread() from any code that is running as a consequence of being part of or called by the run method of an object that extends thread, you get a reference to that instance of that object. This is essentially the long way of saying what Juned said above.
Additionally, I humbly submit that you may be mixing languages; CurrentThread is a class in C# but not in Java.
Related
Code:
public class ThreadTest {
public static void main(String[] args) {
MyImlementThread mit = new MyImlementThread();
Thread t = new Thread(mit);
t.start();
t = new Thread(mit);
t.start();
}
}
// MyImlementThread
class MyImlementThread implements Runnable {
public void run() {
System.out.println("This is implemented run() method");
}
}
/*
Output
This is implemented run() method
This is implemented run() method
*/
What happens here is the main thread starts two threads and exits. Each of the new threads writes a message to stdout, then ends. At that point since all the non-daemon threads have finished the JVM exits.
The posted code is confusing on account of it defining a Runnable but giving it a name ending in Thread.
A Thread object relates to an os-level thread, calling start on a Thread makes the code in the run method of the passed-in Runnable execute run on a separate thread from the one that called start.
The Runnable defines a task but doesn't specify how it runs. It could be passed into a specific Thread's constructor or submitted to an Executor or run by the current thread.
In this case the Runnable declared has no state, no instance variables are declared. Here two threads can execute the same Runnable without a conflict because there is no shared state. The printstream that writes to the console is synchronized, so the lines written by the threads each get written one at a time and don't get jumbled together.
Can anyone explain to me why the first thread doesn't work and the second works perfectly:
public class Test {
public static void main(String args[]) throws InterruptedException {
TestThread1 t1 = new TestThread1();
TestThread2 t2 = new TestThread2();
t1.startThread();
t2.start();
Thread.sleep(4000);
t1.stopThread();
t2.stopThread();
}
}
class TestThread1 extends Thread {
private volatile TestThread1 thread;
public void startThread() {
thread = new TestThread1();
thread.start();
}
public void run() {
while (thread != null) {
System.out.println("RUNNING 1 ...");
}
}
public void stopThread() {
thread = null;
}
}
class TestThread2 extends Thread {
private volatile boolean finished = false;
public void run() {
while (!finished) {
System.out.println("RUNNING 2 ...");
}
}
public void stopThread() {
finished = true;
}
}
When I debug inside TestThread1 class: Inside startThread, the thread member is filled (so it is not null), inside run, thread member is null!!! And finally, inside stopThread, the thread member is not null!!!
Can anyone explain to me what is happening here?
Here, you have two instances of TestThread1 t1:
One is stored into your t1 local variable (in your main method).
One is stored into your thread instance variable (of t1).
t1 is never started, t1.thread is.
t1.stopThread() sets t1.thread to null, but it doesn't affect t1.thread.thread.
Since you're starting t1.thread, its run method is using t1.thread.thread:
This is never set to anything (so it's using null).
Calling t1.stopThread() like you do would only set t1.thread to null, which wouldn't affect t1.thread.thread.
More generally, you can't just "kill" a thread as such, but you can implement tests within the method to tell it to return under certain circumstances. What you've done with your second test is closer to this (using while (!finished) { ... } with a volatile variable).
I wouldn't limit the test to finished. It's also useful to test whether the thread was interrupted, in particular because if you run your runnables within an ExecutorService shutdownNow() will try to interrupt them (see this question).
I'd use while (!finished && !Thread.currentThread().isInterrupted()) { ... }.
(Note the difference between Thread.currentThread().isInterrupted() and Thread.interrupted(): they may seem similar, but the latter will also reset the status, which you might not want.)
Depending on what's within your loop (or whether there is a loop at all), you may want to use something like if (finished || Thread.currentThread().isInterrupted()) { return; } at various strategic points, where it makes sense.
There is two TestThread1 object being created, one is started and the other is stopped.
I suggest not extending Thread and instead wrapping your Runnable once.
TestThread1 t1 = new TestThread1();
t1.startThread();
This will simply call method startThread() on object t1. Inside this method you are creating a new Thread.
thread = new TestThread1();
thread.start();
But for this Thread thread instance variable is null(It is not null for t1).
So in both cases thread variable should be null.
Because in your main method you create a Thread1 Object. You then run startThread which creates a different Thread1 object inside the first one and sets it to the field thread. You then start the second object which didn't have its own thread field initialized. When run method is run on the second object the condition is false and the while loop doesn't start.
Your object hierarchy looks something like this
t1 (Thread1) {
thread(Thread1): {
thread: null;
run() {
while (thread != null) {...} // this is the method that is run - thread is null here since you never initialized it
}
};
startThread() {} // calls the run method on the nested thread object above
run() {
while (thread != null) {...} // this method is not run since t1.start() is never called in main()
}
}
in your case,
t2.start();
is calling run method directly, it is not creating thread inside startThread method.
so t1.stopThread() makes the volatile thread inside Thread1 class null. so you are getting like that.
solution
use
t1.startThread();
t2.startThread();
instead of
t1.startThread();
t2.start();
which makes 2 threads to create separate threads inside that method.
if you want a single thread of Thread1 then use runnable interface and create 2 threads and call startThread respectively rather than creating extra threads inside main.
I was looking a small example on Threads.For creating Threads we can do in 2 ways either by implementing Runnable interface or by extending Thread.I used the 1st way
package test;
public class test implements Runnable{
public static void main(String args[])
{
test t=new test();
t.run();Thread th=Thread.currentThread();
th.start();
}
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("hi");
}
}
My doubt is when we are calling th.start(); then run() is called.I want to know how.I thought internally there start() may be calling run() so I looked in the documentation of Thread class
The following is the start() declaration in Thread class
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
As you can see inside start(),run() is not called but when we are calling th.start() then automatically overriden run() is called.Can anybody please throw some light in this
The mechanism whereby the run method is invoked on a new thread is extralinguistic: it cannot be represented in terms of Java code. This is the crucial line in the start method:
start0();
start0 is a native method whose invocation will:
cause a new native thread-of-execution to be created;
cause the run method to be invoked on that thread.
Thread th=Thread.currentThread();
th.start();// its call run method automatically
if you call direct run method with class object than its treat as a normal method not thread method
start() method of Thread class is used to start a newly created thread. It performs following tasks:
A new thread starts(with new callstack).
The thread moves from New state to the Runnable state.
When the thread gets a chance to execute, its target run() method will run.
It is not supposed to call the run method. If it does, it will do it in the same running thread.
Just like a program starts in the main method of a class, a new thread starts in the run method of the class. You have to look into native code to find it.
You can find your answer in documentation of Thread.start() method.
http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#start()
Internally start method calls the run method.
Simple experiment may reveal the fact. Call Thread.start() and Thread.run(),, keep a print message statement inside run method. This message will be shown two times because the run method is called two times.
Check this statements in your question code. started flag was false before calling start0, after calling start0() function starrted flag is made true. it means the run method is called withing start0().
boolean started = false;
try {
start0();
started = true;
}
To be precise, the start0 method creates new thred to execute the run method and it returns the current thread.
From oracle official document
" public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
Throws:
IllegalThreadStateException - if the thread was already started.
See Also:
run(), stop() "
If I start a thread in a static block. Will the jvm wait for the thread to finish before it loads the class?
static {
System.out.println("static block");
DataRetrievalThread t = new DataRetrievalThread();
t.run();
}
The reason I'm trying this is because
I want to retrieve data from a server and it's taking way too long to get it. So to persist the data I want to retrieve it and store it in a file so that when the client asks for it - it does not need to make the call to the server to get the information.
If I start a thread in a static block. Will the jvm wait for the thread to finish before it loads the class?
Uh. Yes and no and NO.
First off, your code is not forking a thread. So as it is written it will hold up the class construction although technically the class is "loaded" before the static section runs. That's because you are executing the run() method directly in the current main thread. If you want to fork the thread then you should call t.start();.
If you actually fork the thread with t.start() then no, the thread will run in the background and will not hold up the class initialization.
You really should not be doing something like this. It's a tremendously bad pattern. If you explain what you are trying to accomplish, we should be able to really help.
If you are trying to pre-load data into your program then you should just run the load part early on in main() and don't park it in a static initializer in a class. But if you are running it in the main thread, holding up the program, I don't see why this is any faster then making the request on demand.
One thing to consider is to fork (with t.start()) a background thread to load the data and then have a class which holds the data. If the thread finishes in time then it will have pre-loaded the data. When the program needs the data, it should call the class to get it. If the thread hasn't finished it could do a countDownLatch.await(). When the thread finishes the download it could do countDownLatch.countDown(). So you will get some parallelism.
Something like:
public class DataLoader {
private volatile Stuff data;
private final CountDownLatch latch = new CountDownLatch(1);
// start the thread, called early in main()
public void init() {
// you pass in this so it can call setData
DataRetrievalThread t = new DataRetrievalThread(this);
t.start();
}
// called from the DataRetrievalThread
public void setData(Stuff data) {
this.data = data;
latch.countDown();
}
public Stuff getData() {
if (data == null) {
latch.await();
}
return data;
}
}
With run() you execute the method in the current thread, so after that the class will finish loading. You need to call start() to run the method in a new thread.
I came across a deadlock scenario which can be summarized as the StaticDeadlock class shown below.
This simple program will freeze at o.getClass(). Here's my speculation of what happened, but can someone explain it better?
1) the program enters StaticDeadlock static block
2) thread starts
3) main thread is put in wait for thread to finish, hence can't finish the static block
4) inside thread it access StaticDeadlock.o but StaticDeadlock's static block is not finished yet. Hence the program freezes?
public class StaticDeadlock
{
private static final Object o = new Object();
static {
MyThread thread = new MyThread();
thread.start();
try {
thread.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main (String[] args)
{
System.out.println("all is well.");
}
static class MyThread extends Thread
{
#Override
public void run ()
{
System.out.println("inside mythread");
o.getClass();
}
}
}
Yes, that's pretty much it. The new thread is waiting for the class initializer of StaticDeadlock to complete before it accesses the static member. See section 12.4.2 of the Java Language Specification for more details, in particular these steps:
Synchronize (§14.19) on the Class object that represents the class or interface to be initialized. This involves waiting until the current thread can obtain the lock for that object (§17.1).
If initialization is in progress for the class or interface by some other thread, then wait on this Class object (which temporarily releases the lock). When the current thread awakens from the wait, repeat this step.
If initialization is in progress for the class or interface by the current thread, then this must be a recursive request for initialization. Release the lock on the Class object and complete normally.
If the class or interface has already been initialized, then no further action is required. Release the lock on the Class object and complete normally.
It won't even get past step 1 in the second thread, as the first thread has the lock and won't release it.
Note that it's not calling getClass() which causes the problem - doing anything which requires the value of o will make the second thread wait until the class initializer has completed, which of course won't happen because the first thread is waiting for the second thread to finish.