Java - Println不合适

时间:2011-11-17 01:14:33

标签: java

我有多个线程打印数据。所有数据都打印出来;但是,它们不合适。含义线程2在线程1尚未完成时开始打印,这会导致不一致。我如何保证一致性?含义线程1可以在线程1完成后打印。

8 个答案:

答案 0 :(得分:1)

如果您希望线程1执行的代码在运行线程2之前完成,那么您不需要线程。您可能想看看Java的ExecutorService。具体来说,Executors. newSingleThreadExecutor()。这将允许您安排在另一个线程中运行的任务,但确保它们按顺序运行。

答案 1 :(得分:1)

所以,这就是你想要做的事情(伪代码):

String results[2];

Thread1 thread1 = new Thread1() {
   public void run() {
      // do stuff; collect output
      results[0] = output
   }
};

Thread2 thread1 = new Thread1() {
   public void run() {
      // do stuff; collect output
      results[1] = output
   }
};

thread1.start();
thread2.start();

thread1.join();
thread2.join();

print result[0];
print result[1];

使用java.util.concurrent中的类有更好的方法,但这应该给你一个想法

答案 2 :(得分:0)

这是线程如何工作..如果你开始两个线程,它会像这样的东西1 2 1 2 1 2 1 2

答案 3 :(得分:0)

一旦在线程中完成了run方法,就让它在第二个线程中调用一些东西让它知道它可以打印

答案 4 :(得分:0)

我们无法计算线程何时运行并完成执行。它完全取决于CPU。你可以做的是在第一个线程结束时将一个标志变量更新为一个值,并在第二个线程执行之前检查该值。

答案 5 :(得分:0)

您必须保存线程2输出并打印它,直到线程1为1。按照建议的顺序执行它们也会起作用但是,为什么要使用Thread?

答案 6 :(得分:0)

从您的评论中,您希望实现1 1 1 1 2 2 2 2所以您需要做的是等待Thread1完成,然后启动Thread2,如下所示:

Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();

thread1.start();

thread1.join(); // This waits for Thread1 to finish before starting Thread2
thread2.start();

但是,如果你想让两个线程都启动,但让Thread2在处理过程中一直等待,同时等待Thread1完成 - 这可以通过一些技巧来完成 - 特别是想到一个 - 使用{{ 1}}

示例:

好的,首先定义你的线程构造函数来接受一个信号量,因此:

Semaphore.

Thread1的run方法如下所示:

// Thread2 would be identical wrt the semaphore
public Thread1(Semaphore semaphore) throws InterruptedException
{
  this.semaphore = semaphore; // store semaphore locally
  semaphore.acquire(2);
}

Thread2的run方法看起来类似于:

public void run()
{
  // .... processing...

  // ... print stuff
  System.out.println("1 1 1 1");
  semaphore.release(); // release 1 permit, allowing thread2 to continue

  // ... more processing

  semaphore.release(); // release last permit.
}

现在,设置线程将如下所示:

public void run()
{
  int permits = 2;
  try
  {
    // .... processing...

    semaphore.acquire(1); // acquire one more permit (will block until Thread1 releases one)
    permits++;

    // ... print stuff
    System.out.println("2 2 2 2");

    // ... more processing      
  }
  catch (InterruptedException ie)
  {
    // interrupted
  }

  semaphore.release(permits); // release permits.
}

答案 7 :(得分:-1)

您不能从多个线程中随机打印并期望任何订单。

如果你需要以有序的方式输出,那么你将不得不同步线程(从而破坏了拥有多个线程的目的)或者让线程传回信息以输出回主线程,所以它可以处理订购和输出。

编辑:因为我很无聊。

如果您尝试通过线程并行化某些工作然后输出结果,则需要让线程将其工作的产品传递回主线程并让它执行输出。一种方法是使用队列(这是依赖于线程顺序的简单示例 - 您可能需要获取所有结果并关联/排序/等):

public class Worker implements Runnable
{

    private ConcurrentLinkedQueue<Integer> outputQueue;

    public Worker(ConcurrentLinkedQueue<Integer> outputQueue)
    {
        this.outputQueue = outputQueue;
    }

    @Override
    public void run()
    {

       // Do whatever it is you're doing
       ...
       // place result on queue
       outputQueue.add(result);

    }

} 

public class Main
{

    static void main(String[] args)
    {

        ArrayList<ConcurrentLinkedQueue<Integer>> myQueues =
            new ArrayList<ConcurrentLinkedQueue<Integer>>();

        Thread[] myThreads = new Thread[numThreads];

        // Create queue, create thread with Worker(queue),  
        // start thread
        for (int i = 0; i < numThreads; i++)
        {
            ConcurrentLinkedQueue<Integer> queue =
                new ConcurrentLinkedQueue<Integer>();

            myQueues.add(queue);           

            myThreads[i] = new Thread(new Worker(queue)).start();

        }

        // Wait for all threads to finish, print their results
        for (int i = 0; i < numThreads; i++)
        {
            join(myThreads[i]);

            // Get the queue for the thread we just joined, 
            // pull off each result and output
            Integer j;
            while ((j = myQueues.get(i).poll()) != null)
            {
                System.out.println(j);
            }

        }
    }
}

这是我的头脑,但这是一般的方法