0

シーケンスが 30 に達するまで奇数と偶数を順番に出力するマルチスレッド プログラムを作成しました。

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

public class NumPrintTX
{
public static void main(String[] args)
{
    final int max = 31;
    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);
}
}

プログラムを実行すると、問題なく実行されますが、次の行に移動しないため、次にやりたいことのために別のコマンドを入力できます。これがなぜなのか、それを修正するために私にできることはありますか?

変更されたコード: import java.util.concurrent.Executor; java.util.concurrent.Executors をインポートします。java.util.concurrent.atomic.AtomicInteger をインポートします。

public class NumPrintTX
{
public static void main(String[] args)
{
    final int max = 31;
    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);
}
public void close()
{
System.exit(0);
}
}
4

3 に答える 3

1

スレッドプールを停止していないため、メインプログラムを終了させて​​いません。

次のコードを検討してください。

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

class Worker implements Runnable {
    private AtomicInteger i;
    private Object lock;
    private int max;
    private int mod;

    Worker(AtomicInteger i_, Object lock_, int max_, int mod_){ 
        this.i   = i_;
        this.lock = lock_;
        this.max  = max_;
        this.mod  = mod_; 
    }

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

                synchronized(lock){ lock.notify(); }
            }
            else
            {
                synchronized(lock)
                {
                    try { lock.wait(); }
                    catch (InterruptedException e) { e.printStackTrace(); }
                }
            }
        }
    }
}

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

        final Object lock = new Object();

        dd.execute(new Worker(i, lock, max, 0));
        dd.execute(new Worker(i, lock, max, 1));

        dd.shutdown();
    }    
}

がないdd.shutdown()と、最後まで行ってもプログラムがハングします。

メインの do-while ループは機能しますSystem.exit(0)が、少し「総当たり」のようです。

また、このコードによってスレッド コードが合理化され、基になるロジックを変更することなく、はるかに読みやすくなります。

于 2012-10-23T23:49:58.260 に答える
0

「通常の」終了の終了ステータスコードがSystem.exit(0);どこにあるかを呼び出して、プログラムを終了する必要があります。0番号を出力するループが完了した後に呼び出しを行う必要があります。

System.exit(int status)用のJavaドキュメント

于 2012-10-23T23:43:12.223 に答える
-1

プログラムを明示的に閉じる必要があります。だから、このようなもの:

public void close() {
    // Put any closing code here, like joining Threads or whatever
    System.exit(0); // 0 means it is a normal exit, i.e. there are no errors
}
于 2012-10-24T00:00:56.600 に答える