-8

奇数と偶数を別々のスレッドで出力するアルゴリズムが必要です。出力はシーケンシャルである必要があります1,2,3.4 ,.....Executorフレームワークはここで使用できます。SOに関する関連する質問を見たことがありますが、それはCです。ここにJavaの実装が必要です。

4

7 に答える 7

2

ジェイソンの修正版:

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");
}
}

免責事項:これは最善の解決策ではなく、確かに最速ではありませんが、適切な出力を生成します。

それが出力です:

 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
于 2012-07-10T11:28:06.813 に答える
1

出力を順番に並べたいように見えるので、あなたの質問は少し混乱しています。

その場合、スレッドを使用しても意味がありません。現在の番号を出力する順番を決定するためにスレッドが常に相互に調整しているからです。

順序付けを気にしない場合 (たとえば、1,2,3,5,4,6,8.7 など)、意味があるかもしれません。

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);
    }
}
于 2012-07-10T11:21:16.770 に答える
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");
}
于 2012-07-10T11:17:24.760 に答える
0

/* Semaphore を使用すると、偶数奇数列を出力する最も簡単な方法でした */

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));

    }

}
于 2016-09-14T07:02:52.593 に答える
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();
        }
    }
}
于 2013-08-29T13:05:18.923 に答える
0

最も単純なビジー待機コード。

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!");
    }

}
于 2012-07-10T15:43:57.127 に答える