I found this code on a tutorial website:
class NewThread implements Runnable {
Thread t;
NewThread() {
// Create a new, second thread
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for the second thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
In the following line, what is the purpose of the arguments, and what is the meaning of this in the first argument:
t = new Thread(this, "Demo Thread");
Also, what is the expected behaviour (flow) of this code?
When creating a new Thread object you must pass in a Runnable object (which does the actual work in its run() method) as the first argument to the constructor. The second argument is a name for the thread. So, in your code, the following line in the NewThread class constructor:
t = new Thread(this, "Demo Thread");
Creates a new Thread object t named Demo Thread using itself (an instance of NewThread) as the Runnable task, since it implements the Runnable interface. Then, when t.start() is called, the run() method of the NewThread instance t is called.
The API documentation for java.lang.Thread and java.lang.Runnable give more details.
So, your code creates a NewThread object, which starts a child thread in the constructor running the Child Thread loop, and the Main Thread loop is executed by the rest of the code in your main() method. I would expect to see output from the child thread interleaved with output from the main thread when this is run.
Also, when catching InterruptedException and not re-throwing it, it is good practice to restore the interrupted status of the thread, something like this:
} catch (InterruptedException ie) {
System.out.println("Interrupted: " + ie.getMessage());
Thread.currentThread().interrupt();
}
This tutorial by Brian Goetz is very good if you want to learn more about Java threading. It's part of an IBM developerWorks Java concurrency training module.
The line t = new Thread(this, "Demo Thread") is creating a new thread passing the instance of java.lang.Runnable that the thread should execute and the name to give the thread (commonly used during logging operations).
It's a bit weird to have the class implementing java.lang.Runnable create the thread itself. Take a look at the examples of how to use threads on the JavaDoc for java.lang.Thread.
The constructor used in t = new Thread(this, "Demo thread") allows to pass a target. The target must be a Runnable. The target's run() method will be invoked as a result of starting t, so the Thread is created and runs. See the documentation
That's some seriously messed up code up there. OP, you did not write this, but you'll take heat just for stumbling on it.
First of all: The NewThread is not a thread, it's a Runnable. Not the same thing, and for a reason. But then its constructor declares a new thread and starts it right away, turning the Runnable into some sort of a Zombie Thread, which defeats the whole purpose of having a Runnable in the first place, and is just a terrible idea, because if you wanted a Thread, you'd declare a Thread, not a Runnable. What if you want to use the Runnable in a ThreadPool? What if you want to define more than one of these Runnables and start them in a orderly fashion? What if the Runnable one day becomes a Callable, where would you see its Future?
Then, to add insult to injury, the code has concurrent code in the main thread. This servers no educational purpose, and has almost no real-life value, because in real life, you normally don't mix threaded code like that, you'd rather have one control thread (main) and 1..n worker threads (controlled by main).
The point of Threads and Runnables is to separate the functional description of the task (that's the Runnable) from the life-cycle behavior (that's the Thread). Parallel execution and scalability is a nice side benefit. So let's refactor the tutorial code to reflect that:
class Countdown implements Runnable {
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ThreadDemo2 {
public static void main(String args[]) {
Thread t = new Thread(new Countdown());
t.start();
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
That's better. Now the Runnable does no longer pretend to be a Thread, nor does it even care about when or how or by whom it is going to be run. All it does is implement run() which does what the task is supposed to do, and the main thread gives this Runnable as a constructor argument to a new Thread and then start()s it, which in turn means the new Thread will call the Runnable's run(). But we can do better: the two threads do essentially the same thing, so we should implement them that way:
class Countdown implements Runnable {
final String name;
final int length;
final int skip;
public Countdown(String name, int length, int skip) {
this.name = name;
this.length = length;
this.skip = skip;
}
public void run() {
try {
for(int i = length; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(skip);
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println("Exiting " + name);
}
}
public class ThreadDemo3 {
public static void main(String args[]) {
Thread t1 = new Thread(new Countdown("Child One", 5, 50));
Thread t2 = new Thread(new Countdown("Child Two", 5, 100));
t1.start();
t2.start();
}
}
Now we have separated functionality from life-cycle management. Countdown is it's own class which does exactly what the name says and not more, and there is no more worker logic in main. Main just invokes countdowns and starts them.
OP, my biggest advice is: find a better tutorial. The Brian Goetz tutorial mentioned by grkvlt above is much better. You might want to invest some money on books by Goetz ("Java Concurrency in Practice") and Doug Lea ("Concurrent Programming in Java"), too.
Related
This question already has answers here:
When would you call java's thread.run() instead of thread.start()?
(14 answers)
Closed 8 years ago.
I learned that to start a thread the recommended way is to invoke start() method on thread object. But this in turn invokes the run() method. So why not directly invoke run() method?
Here's what I tried but I fail to bring any conclusion :
public class Tester {
public static void main (String[] args) {
Runner r = new Runner();
Thread t1 = new Thread(r, "Thread A(runnable)");
Thread t2 = new Thread(r, "Thread B(runnable)");
Thread s1 = new Strider("Thread C");
Thread s2 = new Strider("Thread D");
t1.run(); // t1.start();
t2.run(); // t2.start();
s1.run(); // s1.start();
s2.run(); // s2.start();
}
}
class Runner implements Runnable {
private int counter;
public void run() {
try {
for (int i = 0; i != 2; i++) {
System.out.println(Thread.currentThread().getName() + " Runnable: "
+ counter++);
Thread.sleep(1000);
}
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
class Strider extends Thread {
private int counter;
Strider(String name) {
super(name);
}
public void run() {
try {
for (int i = 0; i != 2; i++) {
System.out.println(Thread.currentThread().getName() + ": "
+ counter++);
Thread.sleep(1000);
}
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
OUTPUT (using start()) : varies
Thread A(runnable): 0
Thread C: 0
Thread B(runnable): 1
Thread D: 0
Thread B(runnable): 3
Thread D: 1
Thread A(runnable): 2
Thread C: 1
OUTPUT (using run()) : always remains same
main Runnable: 0
main Runnable: 1
main Runnable: 2
main Runnable: 3
main: 0
main: 1
main: 0
main: 1
Also kindly provide your opinion on why not to use run() directly ?
Calling the run method directly does not start the thread but is a synchronous call like any other method call in Java. Hence the output remains always the same.
Only when you call the start method, actual Java infrastructure is involved and a new thread is created, which then calls the run method.
If you call the run method explicitly, no new thread is going to be
started. Calling run() directly just executes the code synchronously
(in the same thread), just like a normal method call.
The Thread class' run() method does nothing, so sub-classes should override the method with code to execute in the second thread. If a Thread is instantiated with a Runnable argument, the thread's run() method executes the run() method of the Runnable object in the new thread instead.
Depending on the nature of your threaded program, calling the Thread run() method directly can give the same output as calling via the start() method, but in the latter case the code is actually executed in a new thread.
Java Code:
// Create a second thread.
class NewThread implements Runnable
{
Thread t;
NewThread()
{
t = new Thread(this, "Demo Thread"); // Create a new, second thread
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
public void run() // This is the entry point for the second thread.
{
justCall();
}
public synchronized void justCall()
{
try
{
for(int i = 10; i > 0; i--)
{
System.out.println("Child Thread: " + i);
Thread.sleep(10000);
}
}
catch (Exception e)
{
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class ThreadDemo
{
public static void main(String args[])
{
NewThread nt = new NewThread(); // create a new thread
try
{
for(int i = 5; i > 0; i--)
{
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
here you can delete the synchronized justCall() method and you can initialize a synchronization block in a run() method(put justCall() method's code in a synchronized block).
How to synchronize child code here? Please Help. I read that Thread.sleep() method never releases the lock while it is executing in the synchronization block or method. But in my code main thread and child code executes concurrently. Please help to synchronize the child code using Thread.sleep() method.
When two threads synchronize on the same object, they will not both run that same code. This allows many different threads to cooperate running in many different areas of code at the same time.
A synchronized on a non-static method creates a lock on the this object. If it had been a static method the lock would have been on the Class object for the NewThread class. Any class and any instance of any class can have a syncronized on it and thus create a lock.
You have only one thread running in the synchronized area. So, while it is locked, no other thread is attempting to run the locked code. No other thread is attempting to synchronize on the nt instance of the NewThread class.
You might want to try doing this:
NewThread nt1 = new NewThread(); // create a new thread
NewThread nt2 = new NewThread(); // create a 2nd new thread
Then leave off the looping in the main class.
i have a task to make 3 (A,B,C) services depending on each other. When service A starts, service B can start, when service B starts , service C can start and when C stops, B can stop, and when B stops A can stop.
I have manage to start threads and make a switch from one to another with status option. I have to say that i dont know so much things about java but i have just started to learn java so i'm new in this so any help,suggestion and etc would be great.
Also I have 3 almost the same classes so can anyone tell em how can I replace those 3 classes with one? Is there any way?
Here is my code:
public class service_class {
int status=1;
public static void main(String[] args) {
service_class service_class = new service_class();
A1 a=new A1(service_class);
B1 b=new B1(service_class);
C1 c=new C1(service_class);
a.start();
b.start();
c.start();
}
}
class A1 extends Thread{
service_class service_class;
A1(service_class service_class){
this.service_class = service_class;
}
#Override
public void run() {
try{
synchronized (service_class) {
while(service_class.status!=1){
service_class.wait();
}
System.out.print("A started" + "\n");
service_class.status = 2;
service_class.notifyAll();
while(service_class.status!=7){
service_class.wait();
}
System.out.print("A stoped" + "\n");
service_class.status = 1;
service_class.notifyAll();
}
}catch (Exception e) {
System.out.println("Exception 1 :"+e.getMessage());
}
}
}
class B1 extends Thread{
service_class service_class;
B1(service_class service_class){
this.service_class = service_class;
}
#Override
public void run() {
try{
synchronized (service_class) {
while(service_class.status!=2){
service_class.wait();
}
System.out.print("B started " + "\n");
service_class.status = 4;
service_class.notifyAll();
while(service_class.status!=6){
service_class.wait();
}
System.out.print("B stoped" + "\n");
service_class.status = 7;
service_class.notifyAll();
}
}catch (Exception e) {
System.out.println("Exception 2 :"+e.getMessage());
}
}
}
class C1 extends Thread{
service_class service_class;
C1(service_class service_class){
this.service_class = service_class;
}
#Override
public void run() {
try{
synchronized (service_class) {
while(service_class.status!=4){
service_class.wait();
}
System.out.print("C started" + "\n");
service_class.status = 5;
service_class.notifyAll();
while(service_class.status!=5){
service_class.wait();
}
System.out.print("C stoped" + "\n");
service_class.status = 6;
service_class.notifyAll();
}
}catch (Exception e) {
System.out.println("Exception 4 :"+e.getMessage());
};
}
}
I have 3 almost the same classes so can anyone tell em how can I replace those 3 classes with one? Is there any way?
It looks like the differences between the 3 classes A, B and C are:
the name string that gets printed, and
the state values that each one tests and sets.
So just replace these with final instance variables, and initialize them with values passed to the (unified) classes constructor.
However ...
Extending Thread is generally thought to be a bad idea. For a start, it makes it difficult to use thread pooling. A better approach is to use the standard Thread class, and pass it a Runnable instance when you construct it. In fact, if you are using thread pooling or and Executor service or whatever, you won't even need to create and manage the threads yourself.
As for the wait / notify stuff, it is easier to use a higher level synchronization construct (such as CountDownLatch).
Use CountDownLatch
A CountDownLatch is initialized with a given count. The await method block until the count reaches zero due to invocations of the countDown() method (by other threads), after which all waiting threads are released. My suggestion is writing a superclass that:
provides a latch with a initial count of 1
accepts another instance of that class or a CountDownLatch that is to be waited before execution
decrements its latch on start
wraps that logic in run and provides an abstract method innerRun where the actual code will be implemented.
abstract class LatchedRunnable extends Runnable {
private CountDownLatch latch=new CountDownLatch(1);
private CountDownLatch wait;
public Foo(LatchedRunnable waitFor) {
this.wait=waitFor.latch;
}
public Foo(CountDownLatch waitFor) {
this.wait=waitFor;
}
final run () {
//wait for the other thread
if (wait!=null)
try {wait.await();}
catch (InterruptedException e) {return;}
//signal that we have started
latch.countDown();
//actually start
innerRun();
}
protected abstract void innerRun(); //do stuff here
}
class Foo extends LatchedRunnable {
Foo(LatchedRunnable waitFor) {super(waitFor);}
protected void innerRun() {...}
}
class Bar extends LatchedRunnable {
Bar(LatchedRunnable waitFor) {super(waitFor);}
protected void innerRun() {...}
}
Foo foo = new Foo(null);
Bar bar = new Bar(foo);
CountDownLatch, in my understanding, is a mechanism to achieve synchronization without entering a deadlock. So here it goes,
Consider, Thread1 performs a task such a file read. Once complete file has been read, another thread could process the file contents and grab certain information. And now a third thread is responsible to copy the information to a DB.
Assume there are multiple clients using the same steps above and in the same order:
FileRead
FileProcessor
DBUpdate
Instead of handling everything sequentially, we create three thread pools.
ThreadPool<FileReaderThread> poolA;
ThreadPool<FileProcessorThread> poolB;
ThreadPool<DBUpdate> poolC;
As a new request comes in, a countdownlatch will be created with an appropriate count. As a thread from poolA completes its work, the count will be decremented. Once this count reaches 0, thread from poolB will be invoked.Similarly another countdownlatch will used to synchronize thread from poolB and poolC. Ideally, we achieve a sequential process with CountDownLatch.
Please correct if something is incorrect.
Not sure sure if I am doing this right. I need to make a new thread to write out message certain number of times. I think this works so far but not sure if its the best way of doing it. Then i need to display another message after thread has finished running. How do I do that ? Using isAlive() ? How do i implement that ?
public class MyThread extends Thread {
public void run() {
int i = 0;
while (i < 10) {
System.out.println("hi");
i++;
}
}
public static void main(String[] args) {
String n = Thread.currentThread().getName();
System.out.println(n);
Thread t = new MyThread();
t.start();
}
}
Till now you are on track. Now, to display another message, when this thread has finished, you can invoke Thread#join on this thread from your main thread. You would also need to handle InterruptedException, when you use t.join method.
Then your main thread will continue, when your thread t has finished. So, continue your main thread like this: -
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Your Message");
When your call t.join in a particular thread (here, main thread), then that thread will continue its further execution, only when the thread t has completed its execution.
Extending the Thread class itself is generally not a good practice.
You should create an implementation of the Runnable interface as follows:
public class MyRunnable implements Runnable {
public void run() {
//your code here
}
}
And pass an intance of it to the thread as follows:
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
Please check this answer here on SO: Implementing Runnable vs. extending Thread
This is how you can do that.........
class A implements Runnable
{
public void run()
{
for(int i=1;i<=10;i++)
System.out.println(Thread.currentThread().getName()+"\t"+i+" hi");
}
}
class join1
{
public static void main(String args[])throws Exception
{
A a=new A();
Thread t1=new Thread(a,"abhi");
t1.start();
t1.join();
System.out.println("hello this is me");//the message u want to display
}
}
see join() details on
join
I want to restart a thread for some use, for example in the below code.
class Ex13 implements Runnable {
int i = 0;
public void run() {
System.out.println("Running " + ++i);
}
public static void main(String[] args) throws Exception {
Thread th1 = new Thread(new Ex13(), "th1");
th1.start();
//th1.join()
Thread th2 = new Thread(th1);
th2.start();
}
}
When I'm executing the above program , some time i'm getting the output as
Running 1
Running 2
and some time i'm getting only
Running 1
After few run i'm getting only
Running 1 as output.
I'm totally surprise about this behavior. Can any one help me understand this.
if I put the join() then i'm getting only Running 1.
You reuse Thread instance, not Runnable. Thread overwrites its run() method to
public void run() {
if (target != null) {
target.run();
}
}
Where target is the Runnable that you give to the constructor. besides that, Thread has an exit() method that is called by the VM, and this method sets target to null (the reason is this bug). So if your first thread has the chance to finish its execution, its run() method is pretty much empty. Adding th1.join() proves it.
If you want to keep some state, you need to keep reference to your Runnable instance, not the Thread. This way run() method will not be altered.
I don't know why do you need this, but (please note that this code doesn't ensure that th1 is ALWAYS executed before th2, though) :
public static class Ex13 implements Runnable {
AtomicInteger i = new AtomicInteger(0);
CountDownLatch latch;
Ex13(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Running " + i.incrementAndGet());
latch.countDown();
}
}
public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(2);
Ex13 r = new Ex13(latch);
Thread th1 = new Thread(r, "th1");
th1.start();
Thread th2 = new Thread(r);
th2.start();
latch.await(); // wait until both theads are executed
System.out.println("Done");
}
You want the incrementing of i to be synchronized, i.e.
public class Ex13 implements Runnable {
int i=0;
public void run() {
System.out.println("Running "+ increment());
}
private synchronized int increment() {
return ++i;
}
}
The Java Tutorial has a very nice explanation of this given a very similar scenario. The problem is that incrementing a variable is not an atomic operation. Each thread needs to read the current state of i before setting it to the new value. Restricting access to incrementing the variable to one thread at a time assures you will get consistent behavior.
To see whats happening in the System.out.println you can also print the thread name:
Thread t = Thread.currentThread();
String name = t.getName();
System.out.println("name=" + name);
I see you call the two threads with the same runnable object, so they will both use the same "i" variable, in order for you to get Running 1 Running 2 you need to synchronize "i"