等待一个线程在 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
我是 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