-8

I want an algorithm that prints odd numbers and even numbers in separate threads . The output should be sequential 1,2,3.4 ,..... Executor framework can be used here . I have seen a related question on SO but that is in C . I want a Java implementation here .

Community
  • 1
  • 1
Inquisitive
  • 7,476
  • 14
  • 50
  • 61
  • 1
    If you have to be like "the results should be sequential", you're doing it wrong. "Threading" and "sequential" don't go together very well; threads run pretty much when they feel like it. Consider it the price of being able to do two things at once -- you give up some control over exactly *in what order* they get done. If you want stuff to run in a particular order, you'll have to do some synchronization (read: making threads block!) just to get what sequential processing gives you for free. – cHao Jul 10 '12 at 15:54

7 Answers7

2

Its a modified version of jasons:

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class Test {

    public static void main(String[] args){
    final int max = 100;
    final AtomicInteger i = new AtomicInteger(0);
    Executor dd = Executors.newFixedThreadPool(2);

    final Object lock = new Object();

    dd.execute(new Runnable() {
        @Override
        public void run() {
            while (i.get() < max) {
                if (i.get() % 2 == 0) {
                    System.out.print(" " + i.getAndAdd(1));

                    synchronized(lock){
                        lock.notify();
                    }
                }else{
                    synchronized(lock){
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    });
    dd.execute(new Runnable() {
        @Override
        public void run() {
            while (i.get() < max) {
                if (i.get() % 2 != 0) {
                    System.out.print(" " + i.getAndAdd(1));

                    synchronized(lock){
                        lock.notify();
                    }
                }else{
                    synchronized(lock){
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    });
    do {
        try {
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    } while (i.get() != max);
    System.out.println("\nDone");
}
}

Disclaimer: its not the best solution, and for sure not the fastest, but it produces the right output.

Thats the output:

 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
Done
lhlmgr
  • 2,087
  • 1
  • 22
  • 38
1

Your question is a little confusing because it looks like you want the output in sequential ordering.

It doesn't make sense to use threads in that case because they would be constantly coordinating with each other to determine whose turn it is to output their current number.

If you don't care about ordering (e.g. you might get 1,2,3,5,4,6,8.7...), then it might make sense.

public class Test
{
    private static final int NOT_APPLICABLE = 1;

    private final ExecutorService executor;

    public Test()
    {
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(2);

        executor = new ThreadPoolExecutor(2, 2, NOT_APPLICABLE, TimeUnit.SECONDS, queue);
    }

    public void submitTask(Runnable task)
    {
        executor.submit(task);
    }

    private static class Counter implements Runnable
    {
        private int counter;

        public Counter(int start)
        {
            this.counter = start;
        }

        @Override
        public void run()
        {
            while (true)
            {
                System.out.println(counter);
                counter += 2;
            }
        }

    }
    public static void main(String[] args)
    {
        Runnable odd = new Counter(1);
        Runnable even = new Counter(2);
        Test app = new Test();
        app.submitTask(odd);
        app.submitTask(even);
    }
}
Taskmaster
  • 966
  • 8
  • 16
  • 1
    If it's for practice, there's no reason to ask for a ready-made solution on StackOverflow. The OP should read tutorials, and try something. – JB Nizet Jul 10 '12 at 11:28
  • Added code for you to get started with. Note that when I ran it, I got a lot of evens, then a lot of odds, then a lot of evens. – Taskmaster Jul 10 '12 at 11:41
0
public static void main(String[] args) {
    final int max = 100;
    final AtomicInteger i = new AtomicInteger(0);
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (i.get() < max) {
                if (i.get() % 2 != 0) {
                    synchronized (i) {
                        System.out.print(" " + i.getAndAdd(1));
                    }
                }
            }
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (i.get() < max) {
                if (i.get() % 2 == 0) {
                    synchronized (i) {
                        System.out.print(" " + i.getAndAdd(1));
                    }
                }
            }
        }
    }).start();
    do {
        try {
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    } while (i.get() != max);
    System.out.println("\nDone");
}
Jason
  • 1,241
  • 8
  • 16
  • This is the sequence I got after running your code :0 2 1 3 5 4 6 8 7 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 72 71 73 74 75 76 77 78 79 80 82 81 83 85 84 86 88 87 89 91 90 92 93 94 95 96 98 97 99 – Inquisitive Jul 10 '12 at 11:20
  • Sorry, I have updated code, and it works fine in my machine now. – Jason Jul 11 '12 at 02:10
0

Some busy waiting code, the simplest.

package t1;

import java.util.concurrent.atomic.AtomicInteger;

public class Redx implements Runnable{
    private final static int MAX = 99;
    final AtomicInteger next;
    final int odd;

    public Redx(AtomicInteger next, int odd) {
        super();
        this.next = next;
        this.odd = odd;
    }

    public void run(){
        for(;;){
            int n = next.get();
            if (n > MAX)
                break;
            if ((n&1)==odd)
                continue;           

            System.out.print(n+", ");
            if ((n & 0x1F)==0x1F)//new line can be skipped
                System.out.println();
            next.lazySet(n+1);

        }
    }
    public static void main(String[] args) {
        final AtomicInteger next = new AtomicInteger(0);
        Redx x0 = new Redx(next, 0);
        Redx x1 = new Redx(next, 1);
        new Thread(x0).start();
        new Thread(x1).start();
        for(;next.get()<=MAX;)
                Thread.yield();

        System.out.println();
        System.out.println("Done!");
    }

}
bestsss
  • 11,796
  • 3
  • 53
  • 63
0
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class GenerateEvenOddNumberTest {

    public static void main(String[] args) {
        GenerateNumber GenNum = new GenerateNumber();
        ExecutorService es =    Executors.newFixedThreadPool(2);
        es.execute(GenNum);
        es.execute(GenNum);
    }

}

class GenerateNumber implements Runnable{

    private static final AtomicInteger nextId = new AtomicInteger(0);   

    // Thread local variable containing each thread's ID
    private static final ThreadLocal<Integer> count =
        new ThreadLocal<Integer>() {
            @Override protected Integer initialValue() {
                return nextId.getAndIncrement();
        }
    };


    private static final AtomicBoolean bool = new AtomicBoolean(true);  
      // Thread local variable containing each thread's ID
    private static final ThreadLocal<Boolean> even =
        new ThreadLocal<Boolean>() {
            @Override protected Boolean initialValue() {
                return bool.getAndSet(false)    ;
        }
    };  


    boolean isOdd = false;  
    Lock lock = new ReentrantLock();
    Condition checkOdd = lock.newCondition();
    Condition checkEven = lock.newCondition();

    public void printEvenNumber(){
        lock.lock();
        try {
            while(count.get()<500){
                while(isOdd){
                    try {
                        checkEven.await();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println("Thread Name "+Thread.currentThread().getName()+" "+count.get());
                count.set(count.get()+2);
                isOdd = true;
                checkOdd.signal();
            }
        } finally {
            lock.unlock();
        }
    }

    public void printOddNumber(){
        lock.lock();
        try {       
            while(count.get()<500){
                while(!isOdd){
                    try {
                        checkOdd.await();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println("Thread Name "+Thread.currentThread().getName()+" "+count.get());
                count.set(count.get()+2);
                isOdd = false;
                checkEven.signal();
            }
        } finally {
            lock.unlock();
        }           
    }


    @Override
    public void run() {
        if(even.get()){
            printEvenNumber();
        }
        else{
            printOddNumber();
        }
    }
}
0

/* Using Semaphore was the easiet way to print odd-even series */

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

class Even implements Runnable {

    private Semaphore s1;
    private Semaphore s2;
    private static volatile int num = 0;

    Even(Semaphore s1, Semaphore s2) {
        this.s1 = s1;
        this.s2 = s2;
    }

    @Override
    public void run() {
        synchronized (s2) {
            while (num < 99) {
                try {
                    s1.acquire();
                    System.out.print(" " + num);
                    num += 2;
                    s2.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class Odd implements Runnable {

    private Semaphore s1;
    private Semaphore s2;
    private static volatile int num = 1;

    Odd(Semaphore s1, Semaphore s2) {
        this.s1 = s1;
        this.s2 = s2;
    }

    @Override
    public void run() {
        synchronized (s1) {
            while (num < 100) {
                try {
                    s2.acquire();
                    System.out.print(" " + num);
                    num += 2;
                    s1.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

public class ExecOddEvenPrint {

    public static void main(String[] args) {

        ExecutorService exec = Executors.newFixedThreadPool(2);
        Semaphore s1 = new Semaphore(1);
        Semaphore s2 = new Semaphore(0);

        exec.execute(new Even(s1, s2));
        exec.execute(new Odd(s1, s2));

    }

}
0
This will do:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;


 public class Threads implements Runnable{

    static AtomicInteger  x=new AtomicInteger(1);
    public  void generate()
    {
        //System.out.println("In generate");
      synchronized(x){
        if(x.get()%2==0)
            System.out.println(x+" is EVEN");
        else
            System.out.println(x+" is ODD");
        x.incrementAndGet();
        }

    }
    @Override
    public synchronized void run() {        
        //System.out.println("In run");
        generate();
    }

    public static void main(String[] args) {
        //System.out.println("In generateThreads");
            ExecutorService pool=Executors.newFixedThreadPool(10);
            for(int i=0;i<2;i++) // two threads
            pool.submit(new Threads());
            pool.shutdown();
            while (!pool.isTerminated()) {

            }
         //   System.out.println("DONEs");

    }

}