等待一个线程在java中完成

时间:2015-04-05 05:29:40

标签: java multithreading synchronized

我在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线程的理解。

如果(索引%10 == 0&amp;&amp; index == 10)阻止将通知另一个线程运行并等待另一个线程完成,并且同样进行第二个线程。现在它不能第一次工作。但是当index == 20时,thread2停止工作,thread1继续print30。

感谢您的帮助。 :)

3 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:0)

I have wrote one simple code using Shared Objected Class named Counter which will track counter details and wrote two threads ThreadOne and ThreadTwo and Main application class as given below.

As suggested by other, you can use high level lock object like Semaphore or 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();
}
}

Output is as given below.

[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

答案 2 :(得分:-2)

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

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