I am starting to learn threads. I have tried different types of thread creation. From the below code you can see the thread t4, target is new instance of Mythread1 & thread name is "Thread4".
But when I see the output I am not able to find the Thread name "Thread 4" instead I get the name "Thread-4". But this is a naming convention for a default thread name.
I am not able to understand what's wrong. I am sure its very basic mistake. Kindly correct me.
class MyThread1 extends Thread {
MyThread1() {
}
public MyThread1(String nameIn) {
super(nameIn);
}
public void run() {
System.out.println(this.getName());
}
}
class MyThread2 implements Runnable {
Thread ownThread;
public MyThread2() {
}
public MyThread2(String nameIn) {
ownThread = new Thread(this, nameIn);
}
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class ThreadCreation {
public static void main(String[] args) {
//Execution type1, as direct thread object
MyThread1 t1 = new MyThread1();
Thread t2 = new MyThread1();
Thread t3 = new Thread(new MyThread1());
Thread t4 = new Thread(new MyThread1(), "Thread4");
Thread t5 = new MyThread1("Thread5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
//Execution type2, pass the runnable object to thread constructor
Thread t11 = new Thread(new MyThread2());
Thread t22 = new Thread(new MyThread2(), "Thread22");
MyThread2 t33 = new MyThread2("Thread33");
t11.start();
t22.start();
t33.ownThread.start();
}
}
Output:
Thread-0
Thread-2
Thread-1
Thread-4
Thread5
Thread22
Thread-5
Thread33
But when I see the output I am not able to find the Thread name "Thread 4" instead I get the name "Thread-4". But this is a naming convention for a default thread name.
Your problem is in code like this:
Thread t4 = new Thread(new MyThread1(), "Thread4");
This code is using MyThread1 as a Runnable and not as a thread. So when the run() method is called you are then calling getName() on the MyThread1 instance and not on the thread that is actually running and calling your run() method and whose name is "Thread4". That is why the MyThread2 class works because it is using Thread.currentThread() to display the true running thread's name.
When you create a thread, either you need to extend Thread and start it as new MyThread1("Thread4") or implement Runnable and do new Thread(new MyRunnable1(), "Thread4");. Implementing of Runnable is the recommended pattern since it allows you to extend other classes.
You never want to do something like new Thread(new ClassThatExtendsThread(), "name"). That creates a fake Java Thread instance that is going to just confuse you.
In your MyThread1 you print the name of the thread object the method is in. Since you don't specify another name when creating the object, a sequential name "Thread-4" is generated for you.
You should either print the name of the executing thread, like in MyThread2, or create the MyThread1 object with a name:
Thread t4 = new Thread(new MyThread1("Thread4"));
Related
public class LambdaFunctionHandler implements RequestHandler<Object, String> {
#Override
public String handleRequest(Object input, Context context) {
Runnable runnable = new Runnable() {
#Override
public void run() {
System.out.println("Hello");
}
}
Thread thread1 = new Thread(runnable);
thread1.start();
Thread thread2 = new Thread(runnable);
thread2.start();
Thread thread3 = new Thread(runnable);
thread3.start();
Thread thread4 = new Thread(runnable);
thread4.start();
}}
I've tried normally and it works fine. but on the lambda function it will not work properly.
Thread is dying before the complete excution of threads. when return statement called it is automatically stopping threads.
Expected result
Hello
Hello
Hello
Hello
Actual Result
Hello
As people said in the comments, the problem is that you are not waiting for the threads to complete. You return from handleRequest() as soon as you're done starting threads. This tells Lambda that your execution is done, so it suspends your container before those threads have a chance to execute.
"Suspends your container" is the difference between running on Lambda and running locally. When you run locally the JVM actually exits, and it won't do so until all non-daemon threads have finished.
To ensure that all threads run, you need to call explicitly join them before returning from your handler function.
To help you understand how this works, you should also add some more debugging information (use System.err because it's unbuffered):
#Override
public String handleRequest(Object input, Context context) {
Runnable runnable = new Runnable() {
#Override
public void run() {
System.err.println("Hello from " + Thread.currentThread().getName());
}
};
Thread thread1 = new Thread(runnable);
thread1.start();
Thread thread2 = new Thread(runnable);
thread2.start();
Thread thread3 = new Thread(runnable);
thread3.start();
Thread thread4 = new Thread(runnable);
thread4.start();
thread1.join();
thread2.join();
thread3.join();
thread4.join();
System.err.println("handler function exiting");
}}
Why does the following code throws an Exception?
class MyThread extends Thread
{
public static void main (String [] args)
{
MyThread t = new MyThread();
t.start();
System.out.print("one. ");
t.start();
System.out.print("two. ");
}
public void run()
{
System.out.print("Thread ");
}
}
Could you point me out to the JLS?
That's the contract of the start() method :
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.
You can't start a thread twice.
As other responses say, you can't start a Thread twice. However, maybe what you want to do is to start 2 threads: in this case, just instanciate again your thread object:
MyThread t = new MyThread();
t.start();
System.out.print("one. ");
MyThread t2 = new MyThread();
t2.start();
System.out.print("two. ");
I tried to create a five threads, accordingly if one thread invokes the synchronized method on one object(objsyn in this case) then all other threads should wait till the thread finishes with the object. So the output should come from thread 1 to thread 5 in order. But the output is coming out of order.
class synctest extends Thread
{
public synchronized void display()
{
try{Thread.sleep(5000*((long)(Math.random())));}
catch(Exception e){}
System.out.println("From synchornized thread "+ Thread.currentThread().getName());
}
public synchronized void run()
{
synctest objsyn = new synctest();
objsyn.display();
}
public static void main(String args[])
{
synctest objsy = new synctest();
Thread t1 = new Thread(objsy,"Thread 1");
Thread t2 = new Thread(objsy,"Thread 2");
Thread t3 = new Thread(objsy,"Thread 3");
Thread t4 = new Thread(objsy,"Thread 4");
Thread t5 = new Thread(objsy,"Thread 5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
Thread execution order is not guaranteed. Synchronization make sure only one thread executing that block of code at a point of time, it doesn't care whether it is first thread (or) second thread.
If you want really execute a particular logic in order, then you don't really need threading. Remember that when you start a thread, it will be separate thread from main thread. May be answers for this question help you.
I am trying to create few flows in java, my program must to create 3 threads and 1 main thread, and than stop.
I created class with implemented Runnable
class NewThread implements Runnable {
String name;
Thread t;
NewThread(String threadname){
name = threadname;
t = new Thread (this, name);
System.out.println(t);
t.start();
}
public void run (){
try {
System.out.println("111");// why cant see it?
Thread.sleep(1000);
}
catch (InterruptedException e){
System.out.println(e);
}
System.out.println("End Thread");
}
And main:
public class ThreadDemo {
public static void main (String []args){
new Thread ("F");
new Thread ("S");
new Thread ("T");
try {
Thread.sleep(10000);
}
catch (InterruptedException e){
}
System.out.println("End M");
}
}
I think i will get result like 3 string of 111 and one string End M -
111
111
111
End M
but i get just
End M
Can anyone say why i dont get 3 string in result of my program?
You need to create NewThread instances rather than generic Threads for your code to execute:
new NewThread("F");
...
new Thread ("F"); creates a new Thread object named "F", which isn't the same as one of your NewThread objects. You never create any of those, so you shouldn't expect any of their code to run. Also, it's very unusual to create a Thread inside of a Runnable. Instead, you should create a Runnable, then create a Thread to hold your Runnable and start() the Thread. The Java Concurrency tutorial might help clear things up for you.
Find my mistake
I must to write
public static void main (String []args){
new NewThread ("F");
new NewThread ("S");
new NewThread ("T");
instead of
new Thread ("F");
Now its ok.
use following in public static void main:
NewThread th1 = new NewThread ("F");
NewThread th2 = new NewThread ("S");
NewThread th3 =new NewThread ("T");
I have an example that seems strange to me.
public class Join {
public static void main(String[] args) {
Thread t1 = new Thread(
new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
);
Thread t2 = new Thread(t1);
t1.setName("t1");
t2.setName("t2");
t1.start();
try {t1.join();} catch (InterruptedException ie) {}
t2.start();
}
}
We'll see printed only t1.
If we'll comment "t1.join", we'll se the expected output (t1 t2).
Why ?
The second thread is created incorrectly:
Thread t2 = new Thread(t1);
I can't support it by documentation, but in the source code of Thread.run() I see:
if (target != null) {
target.run();
}
Where target is Runnable instance. When the Thread is done, it clears the target variable:
private void exit() {
//...
target = null;
This means that when the first thread is done (join() method) it clears the target and the second thread does nothing. When join() is removed, both access the same target of t1 (race condition).
TL;DR
Never create a thread using another thread instance (even though it implements Runnable). Instead create a separate Runnable and pass it:
final Runnable run = new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
Thread t1 = new Thread(run, "t1");
Thread t2 = new Thread(run, "t2"); //new Thread(t1, "t2"); is incorrect!
t1.start();
t2.start();
You don't need any join()s here, by default these are non-daemon threads.
See also
Java Threading Basics (discussion on #2)
Add before t2.start();:
System.out.println("t1 is alive: " + t1.isAlive());
If main thread is waiting for t1 to die then t2.start() can not run t1's run method. Otherwise, without waiting for t1 to die, t2 can run t1's run method.
This is because main thread waits for t1 to die when you call t1.join().
And when you do this
Thread t2 = new Thread(t1);
you are passing t1 as target object whose run method is called.