【问题标题】:return to command line when program output is done程序输出完成后返回命令行
【发布时间】:2012-10-23 23:40:06
【问题描述】:

写了一个多线程程序,依次打印出奇偶数,直到序列达到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);
}
}

当程序运行时,结果很好,但它不会转到下一行,所以我可以输入另一个命令来执行我接下来想做的任何事情。任何想法为什么会这样以及我可以做些什么来解决它?

修改代码: 导入 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);
}
}

【问题讨论】:

    标签: java multithreading command-line command-prompt


    【解决方案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) 可以工作,但似乎有点“蛮力”。

    此外,此代码简化了您的线程代码,并使其更具可读性,而无需更改底层逻辑。

    【讨论】:

    • 你能说得更具体一点吗?
    • 试过了。当我去编译它时,它给了我一个error: cannot find symbol
    • 它对我来说编译得很好——你复制了包括进口在内的整个东西吗?你能给我一个更具体的错误信息吗?
    • 另外请注意ddExecutorService,而不仅仅是Executor——修复此问题后,您可以访问shutdown() 方法。
    • 导入在那里,看起来它们没有在其他编码中格式化。原始和修改后的编码具有相同的导入,因此如果您需要它们,它们几乎位于最顶端。
    【解决方案2】:

    您需要通过调用System.exit(0); 来退出程序,其中0 是“正常”退出的退出状态代码。应该在打印出数字的循环完成后进行调用。

    Java Docs for System.exit(int status)

    【讨论】:

      【解决方案3】:

      您需要明确关闭您的程序。所以,是这样的:

      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
      }
      

      【讨论】:

      • 您必须在您希望程序结束的地方实际调用该方法,您不能只是将它放在那里并期望它发生。 >_
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 2016-03-10
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 2013-02-19
      相关资源
      最近更新 更多