views:

651

answers:

4

I am fairly naive when it comes to the world of Java Threading and Concurrency. I am currently trying to learn. I made a simple example to try to figure out how concurrency works.

Here is my code:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadedService {

    private ExecutorService exec;

    /**
     * @param delegate
     * @param poolSize
     */
    public ThreadedService(int poolSize) {
     if (poolSize < 1) {
      this.exec = Executors.newCachedThreadPool();
     } else {
      this.exec = Executors.newFixedThreadPool(poolSize);
     }
    }

    public void add(final String str) {
     exec.execute(new Runnable() {
      public void run() {
       System.out.println(str);
      }

     });

    }

    public static void main(String args[]) {
     ThreadedService t = new ThreadedService(25);
     for (int i = 0; i < 100; i++) {
      t.add("ADD: " + i);
     }
    }

}

What do I need to do to make the code print out the numbers 0-99 in sequential order?

+6  A: 

Thread pools are usually used for operations which do not need synchronization or are highly parallel.

Printing the numbers 0-99 sequentially is not a concurrent problem and requires threads to be synchronized to avoid printing out of order.

I recommend taking a look at the Java concurrency lesson to get an idea of concurrency in Java.

Ben S
+3  A: 

The simplest solution to your problem is to use a ThreadPool size of 1. However, this isn't really the kind of problem one would use threads to solve.

To expand, if you create your executor with:

this.exec = Executors.newSingleThreadExecutor();

then your threads will all be scheduled and executed in the order they were submitted for execution. There are a few scenarios where this is a logical thing to do, but in most cases Threads are the wrong tool to use to solve this problem.

This kind of thing makes sense to do when you need to execute the task in a different thread -- perhaps it takes a long time to execute and you don't want to block a GUI thread -- but you don't need or don't want the submitted tasks to run at the same time.

Eddie
+3  A: 

The idea of threads is not to do things sequentially.

You will need some shared state to coordinate. In the example, adding instance fields to your outer class will work in this example. Remove the parameter from add. Add a lock object and a counter. Grab the lock, increment print the number, increment the number, release the number.

Tom Hawtin - tackline
A: 

The problem is by definition not suited to threads. Threads are run independently and there isn't really a way to predict which thread is run first.

If you want to change your code to run sequentially, change add to:

public void add(final String str) {
    System.out.println(str);
}

You are not using threads (not your own at least) and everything happens sequentially.

extraneon
Thats not the point of the exercise.. The example I provided is not something I am really going to use.. I want to understand threading and synchronization better.
Grasper