等待一个线程在 java 内完成

Wait for one thread to finish in java

我是 java 中相对较新的线程,我正在尝试进行以下工作。两个线程将 运行。 Thread1 将从 1-10 打印,然后等待 Thread2 完成打印 11-20,然后完成其任务并通知 thread1 打印 21-30,然后 thread1 也将终止。 这是我使用的代码:

private Thread thread = null;
private String name = null;
private static Object obj = new Object();
private static int index = 1;

public childThread(Thread t, String name)
{
  this.name = name;
  this.thread = t;
}
public void run()
{      
try
{
  while (true) {
    Thread.sleep(500);
    if (index % 10 == 0 && index == 10) {
      System.out.println("Waiting for Thread2");
      synchronized (obj) {
        obj.notify();
        obj.wait();
      }
    }
    else if (index % 10 == 0 && index == 20) {
      System.out.println("Waiting for Thread1");
      synchronized (obj) {
        obj.notify();
        obj.wait();
      }
    }
    else if(index == 30)
    {
      obj.wait();
    }


    synchronized (obj) {
      System.out.println(name + " ><>< " + index);
      index++;
    }
  }
}
catch(Exception e)
{
}

我得到以下输出:

Thread2 ><>< 1
Thread1 ><>< 2
Thread2 ><>< 3
Thread1 ><>< 4
Thread2 ><>< 5
Thread1 ><>< 6
Thread1 ><>< 7
Thread2 ><>< 8
Thread2 ><>< 9
Thread1 ><>< 10
Thread2 ><>< 11
Thread1 ><>< 12
Thread2 ><>< 13
Thread1 ><>< 14
Thread2 ><>< 15
Thread1 ><>< 16
Thread2 ><>< 17
Thread1 ><>< 18
Thread2 ><>< 19
Waiting for Thread1
Waiting for Thread1
Thread1 ><>< 20
Thread1 ><>< 21
Thread1 ><>< 22
Thread1 ><>< 23
Thread1 ><>< 24
Thread1 ><>< 25
Thread1 ><>< 26
Thread1 ><>< 27
Thread1 ><>< 28
Thread1 ><>< 29

基于我目前对 Java 线程的理解。

if(index %10 == 0 && index == 10) 块将通知另一个线程到 运行 并等待另一个线程完成,同样进行对于第二个。现在它第一次不起作用。但是当index == 20时,thread2停止工作,thread1继续打印30.

感谢您的帮助。 :)

这是一个有效的代码,希望对您有所帮助

public static void main(String[] args) {
    final Object lock = new Object();
    final Thread t2 = new Thread() {
        public void run() {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            for(int i = 11; i < 21; i++) System.out.println(i);
        }
    };
    Thread t1 = new Thread() {
        public void run() {
            for(int i = 1; i < 11; i++) System.out.println(i);
            synchronized (lock) {
                lock.notifyAll();
            }
            try {
                t2.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            for(int i = 21; i < 31; i++) System.out.println(i);
        }
    };
    t1.start();
    t2.start();
}

这里的根本问题是你有一个竞争条件,两个线程同时进入循环。

你需要这样安排,只允许一个人进入,另一个必须立即等待。

您可以改为尝试如下所示的循环,它是互斥的。一个线程将被允许进入并开始递增,另一个必须停止,直到第一个线程调用 obj.wait().

synchronized(obj) {
    while (index < 30) {
       Thread.sleep(500);
       if (index > 0 && index % 10 == 0) {
           obj.notify();
           obj.wait();
       }
       index++;
   }
}

我使用名为 Counter 的共享对象 Class 编写了一个简单代码,它将跟踪计数器详细信息并编写了两个线程 ThreadOne 和 ThreadTwo 以及主应用程序 class,如下所示。

正如其他人所建议的,您可以使用高级锁对象,如 Semaphore 或 Lock class。

package thread.communication.demo;

public class Counter {

private int count = 1;

private boolean lockTrue = false;

public synchronized void incrFirstThread() {

    while (lockTrue) {

        try {
            wait();

        } catch (InterruptedException ex) {
            Logger.getLogger(Counter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    lockTrue = true;

    for (int i = count; i < count + 10; i++) {
        System.out.println(i + Thread.currentThread().getName());
    }

    count += 10;

    notifyAll();

}

public synchronized void incrSecondThread() {

    while (!lockTrue) {

        try {
            wait();

        } catch (InterruptedException ex) {
            Logger.getLogger(Counter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    lockTrue = false;

    for (int i = count; i < count + 10; i++) {
        System.out.println(i + Thread.currentThread().getName());
    }

    count += 10;

    notifyAll();
}
}



package thread.communication.demo;

public class ThreadOne extends Thread{

Counter counter;

ThreadOne(Counter counter)
{
    this.counter=counter;
}

@Override
public void run() {

    while (true) {

        counter.incrFirstThread();
    }
}
}

package thread.communication.demo;

public class ThreadTwo extends Thread {

Counter counter;

ThreadTwo(Counter counter)
{
    this.counter=counter;
}

@Override
public void run() {

    while (true) {

        counter.incrSecondThread();
    }
}
}

package thread.communication.demo;

public class ThreadMain {

public static void main(String[] args) {

    Counter counter=new Counter();

    ThreadOne one = new ThreadOne(counter);

    ThreadTwo two = new ThreadTwo(counter);

    one.start();

    two.start();
}
}

输出如下。

[INFO] [INFO] --- exec-maven-plugin:1.2.1:exec (default-cli) @ MultiThreading ---

1Thread-0 2Thread-0 3Thread-0 4Thread-0 5Thread-0 6Thread-0 7Thread-0 8Thread-0 9Thread-0 10Thread-0 11Thread-1 12Thread-1 13Thread-1 14Thread-1 15Thread-1 16Thread-1 17Thread-1 18Thread-1 19Thread-1 20Thread-1 21Thread-0 22Thread-0 23Thread-0 24Thread-0 25Thread-0 26Thread-0 27Thread-0 28Thread-0 29Thread-0 30Thread-0 31Thread-1 32Thread-1 33Thread-1 34Thread-1 35Thread-1 36Thread-1 37Thread-1 38Thread-1 39Thread-1 40Thread-1 41Thread-0 42Thread-0 43Thread-0 44Thread-0 45Thread-0 46Thread-0 47Thread-0 48Thread-0 49Thread-0 50Thread-0 51Thread-1 52Thread-1 53Thread-1 54Thread-1 55Thread-1 56Thread-1 57Thread-1 58Thread-1 59Thread-1 60Thread-1