每个java程序都至少有一个线程给主线程,java程序在主线程中判断各个子线程状态的操作,该如何解决...

java程序在主线程中判断各个子线程状态的操作

每个子线程在队列为空时会wait等待其他线程添加新url到队列,到最后所有子线程都取不到url时也会都wait住,要在主线程中判断如果所有的子线程都是wait状态的话,则终止子线程并退出,该如何判断?下面主线程中我用if判断执行时主线程会被子线程在某一时刻抢走出现错误的wait判断(也就是判断时恰好是等其他线程的wait,这个时刻并不是所有子线程都wait了)吗?

//子线程中:

public void run() {

while(true)

{

String visitingUrl = (String) getAUrl(); //从队列中同步的取一条url

if(visitingUrl==null){                              //队列为空

synchronized(signal){                 //等待其他线程向队列中添加新url的信号

try {

signal.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

......

......

}

}

//主线程中:

//监控线程队列里的每个线程的状态

while(flag){

......

if(threadsList.get(0).getState().equals("WAITING")

&& threadsList.get(1).getState().equals("WAITING")

&& threadsList.get(2).getState().equals("WAITING")){        ——1

flag=false;

}else{

Thread.sleep(2000);

}

......

}

——1 这个地方会不会出现没判断完小括号里语句的就跳转到子线程了?那不就有可能出错了吗,我查了下有说不是原子操作的话就可能会出错,那我这样写正确吗,怎么实现原子操作,如何达到准确判断的要求?

------解决方案--------------------

引用:Quote: 引用:把你的思路换一下。

wait是可以超时的,你可以变成子线程在等3*10秒之后取不到URL就超时。

然后你只需要在wait这里判断一下就可以了。

那是在wait(30000)括号里加时间?可是时间到了自动就醒了又重新循环了啊,怎么确定是自己醒的还是被唤醒的呢,还是不太明白你说的,应该在哪里判断?给个例子最好了

要判断是外面notify还是超时,其实也很简单。

如果是外面的notify,那至少会有两个现像:

1. wait前后的时间差应该<30000

2. 应该有足够让你继续工作下去的条件,如拿到url .

按此两个规则,随便找一个去判断即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是一个实现要求的多线程程序示例,该程序定义了一个线程和100个线程线程通过调用线程来输出1~100之间的偶数,每行输出10个数字。每个线程负责输出1~100之间的某一个整数,每行输出10个数字。为了控制并发访问,程序使用了同步锁(synchronized)来保证每个线程可以正确地输出。 ``` public class MultiThreadProgram { public static void main(String[] args) { Printer printer = new Printer(); for (int i = 0; i < 100; i++) { Thread thread = new Thread(new Task(printer, i + 1)); thread.start(); } printer.printEvenNumbers(); } } class Task implements Runnable { private Printer printer; private int number; public Task(Printer printer, int number) { this.printer = printer; this.number = number; } public void run() { printer.printNumber(number); } } class Printer { private int evenNumber = 2; private int currentNumber = 1; public synchronized void printNumber(int number) { while (number != currentNumber) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.print(Thread.currentThread().getName() + ": " + number + " "); currentNumber++; notifyAll(); } public synchronized void printEvenNumbers() { while (evenNumber <= 100) { while (currentNumber % 2 != 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.print(Thread.currentThread().getName() + ": " + evenNumber + " "); evenNumber += 2; currentNumber++; notifyAll(); if (evenNumber % 20 == 0) { System.out.println(); } } } } ``` 注意,程序使用wait()方法来等待当前线程可以正确地输出数字,并使用notifyAll()方法来通知其他线程可以开始输出。程序还使用了Thread.currentThread().getName()来输出线程的名称,方便观察线程之间的交替输出。 ### 回答2: 以下是一个Java定义的多线程程序,其线程输出1~100之间的偶数,每行输出10个数,线程输出1~100之间的素数,每行输出10个数: ``` // 导入必要的类 import java.util.ArrayList; import java.util.List; // 继承Thread类创建线程 class PrimeThread extends Thread { @Override public void run() { int count = 0; for (int i = 2; i <= 100; i++) { if (isPrime(i)) { // 判断是否为素数 System.out.print(i + " "); count++; if (count % 10 == 0) { // 每行输出10个素数 System.out.println(); } } } } // 判断一个数是否为素数 private boolean isPrime(int number) { if (number <= 1) { return false; } for (int i = 2; i <= Math.sqrt(number); i++) { if (number % i == 0) { return false; } } return true; } } public class Main { public static void main(String[] args) { Thread primeThread = new PrimeThread(); // 创建线程对象 primeThread.start(); // 启动线程 int count = 0; for (int i = 1; i <= 100; i++) { if (i % 2 == 0) { // 判断是否为偶数 System.out.print(i + " "); count++; if (count % 10 == 0) { // 每行输出10个偶数 System.out.println(); } } } } } ``` 这个程序,我们创建了一个继承自Thread类的线程PrimeThread,其的run()方法实现了线程输出1~100之间的素数。然后在线程Main,我们在线程执行前先输出1~100之间的偶数。线程线程同时执行,分别输出各自的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值