Dima Kovbasa
Dima Kovbasa

Reputation: 87

Creates thread in Java

I don't understand, when I creates Thread, what i will get in first case and the second?

And in general, there is difference between them?

ExecutorService executorService = Executors.newCachedThreadPool();

NewThread newThread =  new NewThread(Thread.MAX_PRIORITY);
for(int i = 0;i < 5; i++){
    executorService.execute(newThread);
}

ExecutorService executorService = Executors.newCachedThreadPool();

for(int i = 0;i < 5; i++){
    NewThread newThread =  new NewThread(Thread.MAX_PRIORITY);
    executorService.execute(newThread);
}

Upvotes: 0

Views: 114

Answers (4)

Filip Malczak
Filip Malczak

Reputation: 3194

Best answer, given what you've provided is: in the first case you'll probably get errors. Second way is totally safe (assuming that you're not doing something unsafe, of course).

I know, not much helpful, so let's get you some background.

NewThread most probably implements Runnable, so it should have method void run(), like this:

class NewThread implements Runnable {
    void run(){
          //do something
    }
}

Now, we don't know what's the actual implementation, but we still can do some analysis. The whole outcome of your examples depends on whether NewThread is stateful or stateless. "Stateful" means that instance of that class has state, for example some internal fields (attributes). "Stateless" is just "not stateful".

If NewThread is stateless, then in both cases the outcome will be the same - underneath ExecutorService executes the run() method in new thread, and as there is no state of variables anyway, we won't have any problems.

If NewThread is stateful, there may be some problems in first of your examples. Compiler won't be of much help here, as the code is OK, but the logic may be broken. Imagine this:

class NewThread implements Runnable {
    int x = 0;
    void run(){
          while (x<10)
               x = x + 1;
    }
}

What you see here is a handbook example of race condition. Better authors than me explained the issue way better than me, so I'm just gonna provide some links to read, like this, this and this (also: use Google, of course). Basically, race condition in this case is that when we do x = x + 1 we first need to read x, then write to it. Between read and write some other thread may have modified the value of x, and that would be overwriten by this thread.

There is a case in which NewThread is stateful, but still works properly. This happens if you synchronize your code by-hand - either using synchronized keyword (for example, see 3rd link above) or by using synchronized data structures:

class NewThread implements Runnable {
    AtomicInteger x = new AtomicInteger(0);
    void run(){
          while (x<10)
               x.incrementAndGet(); //getAndIncrement would work too - we don't care about the result, only about incrementing
    }
}

"Atomic" means that every operation on that class is considered single step, like read or write (while x = x+1 are two steps, which is exactly what leads to race condition). There are already several available atomic classes in JDK. If you would like to implement something similiar yourself, you'd probably be using synchronized keyword or some lock-like object to guard the variable.

Upvotes: 1

nasukkin
nasukkin

Reputation: 2540

I haven't tried it, but the first case should execute once and then start throwing exceptions. Once an instance of Thread has terminated, it is illegal to try to start it again. See the javadoc for start:

IllegalThreadStateException - if the thread was already started.

Your second example is the more sensible of the two since it's creating 5 separate Thread instances.

Upvotes: 0

GhostCat
GhostCat

Reputation: 140427

I think your question is rooted in bad naming. You are doing

executorService.execute(newThread);

and probably you are wondering now how why that service (which is based on a threadpool) is dealing with Threads.

Simple answer: it isn't. That interface Executor.execute() takes a Runnable object.

In other words: your code will call that run method that your class NewThread provides.

Of course, the "direct" answer to your question is: in the first case, you are sending the same Runnable 5 times to the Executor; whereas in the second case, you are sending 5 different Runnables to the Executor.

Different in the sense of: different objects - as they are of the same class, the very same thing should happen for both examples. Unless you do some nasty static stuff in NewThread; which wouldn't be too surprising given the overall impression of your question.

Upvotes: 0

tony petrov
tony petrov

Reputation: 73

In the first case you are creating one thread instance and attempting to execute it 5 times in the second you are creating 5 different thread instances and trying to execute them. Does that answer your question?

Upvotes: 0

Related Questions