0

I was wondering if anyone can help me out with a problem.

What I want to accomplish (using Java):

In first iteration, I want to "doStuff" 10 times (concurrently).

In the second iteration, I want to "doStuff" 20 times (in a concurrent manner) AFTER the first iteration is complete.

etc... (I'd like to be able to loop because I plan to do this over 100 times)

The problem with my code is that it's doing stuff 30 times at once. Any help would be greatly appreciated.

PS: Parts of code were removed for simplification so let me know if there are any mistakes.

public static void doStuff(){

 [Code]

}

public static void threadThis (int y){

for (int i = 0; i<y; i++) {
    Thread t1 = new Thread(){
        public void run() {
            doStuff();
        }
    };
    t1.start();
    }

}

public static void main(String[] agrs) throws InterruptedException {


    for (int p = 0; p<21; p = p + 10){
        threadThis(p);
    }
}
5
  • 1
    If you want the second iteration of 20 "doStuff"s to run after the first, you need to implement a hold on the second iteration of threads. Right now there's nothing doing that, so all 30 threads are running and executing when called. Commented Apr 25, 2014 at 14:27
  • Have a look at the fork-join tutorial. Commented Apr 25, 2014 at 14:28
  • Make your own class that extends the Thread class and as soon as the "doStuff()" function finishes set a boolean finished = true. You can check in a loop for all current running threads and if there finish attribute is all true, you can create 10 more threads doing other stuff. Commented Apr 25, 2014 at 14:28
  • Will using public static synchronized threadThis not work? Commented Apr 25, 2014 at 14:45
  • @Roberto Unfortunately this does not work. Same results. Commented Apr 25, 2014 at 14:49

3 Answers 3

2

Here is a good task for CountDownLatch class from java.util.concurrent package.

Naturally you task split off on two big tasks which should be queued, it is exactly CountDownLatch responsibility.

Look for CountDownLatch API documentation, there is a good code sample, could be easely adopted to your needs

Sign up to request clarification or add additional context in comments.

1 Comment

Also OP can consider using CyclicBarrier.
1

You could change threadThis() to join() all of the threads after it starts them.

public static void threadThis (int y){
    List<Thread> threads = Lists.newArrayListWithCapacity(y);
    for (int i = 0; i<y; i++) {
        Thread t1 = new Thread(){...};
        t1.start();
        threads.add(t1);
    }
    for (Thread t : threads) {
        t.join();
    }
}

Comments

0

As the others are saying the concept of CountDownLatch will be very useful here. CountDownLatch is actually using wait and notify underneath. So this is how you can put wait and notify to work and implement a similar functionality yourself.

Main

public class Main 
{
    public static void main(String[] args) 
    {
        Manager mgr = new Manager("manager");
        mgr.start();

    }
}

Manager

    public class Manager extends Thread
    {
        public int threadCount=0;

        private final Object lock = new Object();

        public Manager(String name){
            super(name);
        }


        public void pauseAndWaitForAll()
        {
            synchronized (this.lock) {
                    try {
                        while(this.threadCount>0)
                        {
                            this.lock.wait();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
             }
        }
        public void countDown()
        {
            synchronized (this.lock) {
                this.threadCount--;

// if the if block becomes uncommented notify will only be called
// by last running thread of group, thus will only be called by last running thread of 
// group. If the if block is left commented out then every thread that is done with its 
// work will call notify and thus wait will be called again due to the 
// while(thread.count>0) loop not terminating


                            //if (this.threadCount <= 0) 
                //{
                    this.lock.notify();
                //}
             }
        }

        public void run () 
        {
            for (int p = 10; p<1001; p = p + 10)
            {
                this.threadCount=p;

                for (int i = 0; i<p; i++)
                {
                    System.out.println(" new thread...: "+i+" ");

                    new DoWork(this,"thread: num:"+i+"--group:"+p).start();
                }

                pauseAndWaitForAll();

                // uncomment the following for debugging 
    //          System.out.println(" ------------------next group-----------------------");
    //          try {
    //              Thread.sleep( 3000 ); 
    //          } catch (InterruptedException e) {
    //              System.out.println(" pause error ");
    //          }
            }
        }
    }

DoWork

public class DoWork extends Thread
{
    private Manager managerThread;

    public DoWork(Manager managerThread,String name){
        super(name);

        this.managerThread=managerThread;
    }


    public void run () 
    {
        try {
//          System.out.print(this.getName()+" going to sleep ...: ");
            int randSleep= 1000*(0 + (int)(Math.random() * ((5 - 0) + 1)));
            Thread.sleep(randSleep); 
            System.out.println(this.getName()+" woke up ... ");
        } catch (InterruptedException e) {
            System.out.println(" worker thread: job simulation error:"+e);
        }

        managerThread.countDown();
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.