Java - Creating a New Thread

Java - creating a new thread

You are calling the one.start() method in the run method of your Thread. But the run method will only be called when a thread is already started. Do this instead:

one = new Thread() {
public void run() {
try {
System.out.println("Does it work?");

Thread.sleep(1000);

System.out.println("Nope, it doesnt...again.");
} catch(InterruptedException v) {
System.out.println(v);
}
}
};

one.start();

How to create n threads and work with all of them

The default constructor for the Thread class creates a thread that does nothing. You're calling that default constructor here: thread[i] = new Thread();

If you want the thread to actually do something, then you must provide a Runnable instance as an argument to the Thread constructor. There are a couple of ways to do that. The newest, most concise way is to use a lambda expression:

thread[i] = new Thread(() -> {
System.out.println("Hi");
});

The Runnable interface is an @FunctionalInterface. Since the compiler knows that the Thread(...) constructor wants an object of that type, it infers that that's what the lambda should create, and the body of the lambda becomes the run() method of the new object.


Another, older way to provide a Runnable object is to use an anonymous inner class expression. The syntax is a little more cumbersome because you have to explicitly say what interface the new class should implement, and you have to explicitly declare the run() method:

thread[i] = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hi");
}
});

The oldest way, still even more verbose, is to explicitly declare a named class:

class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Hi");
}
};

public class Principal /*does not need to implement Runnable*/ {
...
thread[i] = new Thread(new MyRunnable());
...
}

You might ask, why did I remove implements Runnable from the Principal class, and create a whole new class?

I did it because, I've read this book: https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/

Create multiple threads by extending Thread class that share same object in Java

Does this snippet create 3 threads?

Your program creates five threads. Each thread is responsible for one of the five lines of output that you showed.

I thought that the thread names that will be printed would be demo2.1, t1, t2 since I passed these names in constructor.

The five threads are named "demo2.1", "t1", "t2", "tR1", and "tR2", but the "t1" and "t2" threads never get to print their own names. That's because you gave each one of them a Runnable delegate, which happens to be the "demo2.1" thread instance.

The run() method of the "demo2.1" instance (the run() method of the Demo2 class) prints its own name, which is not always the name of the thread that is running it.

In more detail:

Here, you create a new object, which is a Demo2, and which is a Thread, and which implements Runnable, and which is named "demo2.1":

Demo2 objT1 = new Demo2("demo2.1")

When you call objT1.start(), the new thread calls the Demo2.run() method, and that method prints this.getName().

OK, That's simple, but the next bit is not so simple.

Here, you create another new object, which is a Thread that uses the previous objT1 as its Runnable delegate, and which is named "t1":

Thread tT1 = new Thread(objT1,"t1");

When you call tT1.start(), the new thread will call it's delegate's run() method. It will call Demo2.run(). But recall that Demo2 is a Thread with a name, and its run method prints its own name (actually, this.getName()) instead of printing the name of the thread that is running it (which would be Thread.currentThread().getName()).

Recap:

You are using objT1 in two different ways:

  1. You use it as a Thread
  2. You use it again, two more times, as the delegate of a different thread.

All three times, it prints its own name, which is not the same as the name of the thread that is running it in the two cases where you use the object as the delegate of a thread.

Does runnable run() create a thread everytime I call it?

No, calling run() of the Runnable interface will not spawn a new thread.
On the other hand, when you wrap the Runnable with a Thread class and call start() then the JVM will spawn a new thread and execute the Runnable in it's context.

In your code, only the Async tasks will run in a separate thread since the Threadpool is managing their execution.

Java force create new instance for a Runnable on each thread

Instead of subclassing Runnable, make your MyRunnable extend Thread...

(and maybe rename it MyThread)

...or you could make the Constructor private & create a static factory-method to return a Thread containing MyRunnable. Something like:

public class MyRunnable implements Runnable {

private MyRunnable() {}

@Override
public void run() {
System.out.println(Thread.currentThread().toString() + " : MyRunnable running");
}

public static Thread getThread() {
return new Thread(new MyRunnable());
}

public static Thread getStartedThread() {
final Thread thread = new Thread(new MyRunnable());
/**/ thread.start();
return thread;
}

public static void main(final String[] args) {
getStartedThread();
getStartedThread();
getStartedThread();
}
}

Is re-starting a Thread better than creating a new one?

It is not possible to start a Thread more than once, but conceptually, the answer to your question is yes.

This is normally accomplished with a thread pool. A thread pool is a set of Threads which rarely actually terminate. Instead, an application is passes its task to the thread pool, which picks a Thread in which to run it. The thread pool then decides whether the Thread should be terminated or reused after the task completes.

Java has some classes which make use of thread pools quite easy: ExecutorService and CompletableFuture.

ExecutorService usage typically looks like this:

ExecutorService executor = Executors.newCachedThreadPool();

for (int i = 0; i < n; i++) {
tasks[i] = () -> {
while (true) {
MyObject input = inputs.poll(1L, TimeUnit.MICROSECONDS);
if (input == null) return;
// run computations over this.dataStructure
}
};
executor.submit(tasks[i]);
}

// Doesn't interrupt or halt any tasks. Will wait for them all to finish
// before terminating its threads.
executor.shutdown();

executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

Executors has other methods which can create thread pools, like newFixedThreadPool() and newWorkStealingPool(). You can decide for yourself which one best suits your needs.

CompletableFuture use might look like this:

Runnable[] tasks = new Runnable[n];
CompletableFuture<?>[] futures = new CompletableFuture<?>[n];

for (int i = 0; i < n; i++) {
tasks[i] = () -> {
while (true) {
MyObject input = inputs.poll(1L, TimeUnit.MICROSECONDS);
if (input == null) return;
// run computations over this.dataStructure
}
};
futures[i] = CompletableFuture.runAsync(tasks[i]);
}

CompletableFuture.allOf(futures).get();

The disadvantage of CompletableFuture is that the tasks cannot be canceled or interrupted. (Calling cancel will mark the task as completing with an exception instead of completing successfully, but the task will not be interrupted.)



Related Topics



Leave a reply



Submit