在main()函数中有100个线程,我希望等这些线程全部执行完毕后再执行一条语句,请问应该如何做?不能让这100线程全部join()吧?
public static void main(String[] args){
for(int i = 0; i < 100; i++){
new MyThread().start;
} /*这里应该如何处理?*/
System.out.println("线程全部执行完毕");
}
public static void main(String[] args){
for(int i = 0; i < 100; i++){
new MyThread().start;
} /*这里应该如何处理?*/
System.out.println("线程全部执行完毕");
}
public static clear(){count=0;}
}线程执行完时候执行下threadFlag.addOne();main里判断:
if(threadFlag.count=100){ //打印}else{ wait();//等待}
是不是还要getThreadGroup() 来获得线程组?isAlive()可以对线程组操作么?
public static minusOne(){count--};
public static clear(){count=0;}
}线程构造函数里执行下threadFlag.addOne();线程执行完时候执行下threadFlag.minusOne();main里判断:
if(threadFlag.count==0){ //打印}else{ System.out.println("还有"+threadFlag.count+"个线程未完成!") wait();//等待}
private int typeBcount;
private int typeCount;
private int typeDcount;
...private threadFlag(){
typeAcount=0;
typeBcount=0;
typeCcount=0;
typeDcount=0;
..
}public static synchronized threadFlag getInstance() {
if ( flag == null ) flag = new threadFlag();
return flag ;
}public void addTypeAcount() {typeAcount++;}
public void minusTypeAcount() {typeAcount--;}
public int getTypeAcount(){return typeAcount;}
....public void clear(){
typeAcount=0;
typeBcount=0;
typeCcount=0;
typeDcount=0;
..
}}不同类型的线程可以使用不同的记数器:
你甚至可以给同一个类型的线程写一个父类,比如:
class TypeAThread implements Runnable {....
public TypeAThread(){
threadFlag.getInstance().addTypeAcount();
}
..
}
hashtable里面没记录了,证明所有线程都执行完毕,然后再执行你想要的东西.
另外怎么给分阿?
我觉得按照你的思路,没有必要使用HashTable,只需要一个List就可以了。
只要启动一个线程,就将其自身add到list中,执行完毕后将其从list中删除即可。
最后检查list是否为空就好了。你说呢?
public static int count = 0;
public static int amount = 0;
private static Random rand = new Random();
MyThread(int i){
amount += rand.nextInt(i);
}
public void run(){
ThreadControl.add(this);
System.out.println("Number " + ++count +" thread: I am running.");
try{
sleep(200);
}catch(InterruptedException e){}
ThreadControl.del(this);
}
}public class ThreadControl extends Thread {
private static List threadList = new ArrayList();
public static synchronized void add(Thread t){
threadList.add(t);
}
public static synchronized void del(Thread t){
threadList.remove(t);
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
while (MyThread.amount < 1000){
new MyThread(10).start();
}
boolean over = false;
while(!over){
if (threadList.isEmpty()){
over = true;
System.out.println("There are " + MyThread.count + "threads running over.");
System.out.println("The amount number is " + MyThread.amount);
try{
sleep(1000);
}catch(InterruptedException e){}
}
}
long endTime = System.currentTimeMillis();
long interval = endTime- startTime;
System.out.println("Time consumption: " + interval + " ms.");
}}
如果将run()方法中的sleep(200)改成sleep(20)的话,那么你的程序将会出错!
所以为了保证稳定性应该将main()方法中的判断线程结束的if (threadList.isEmpty())改为
if (MyThread.amount >= 1000 && threadList.isEmpty())
不知你认为如何
ArrayList不是线程安全的,你应该在你的ThreadControl 里面加上一个synchronized的isEmpty方法。
同时我看这个问题应该是wait/notify的问题,不知道为什么诸位都不用,不理解,还望各位指教!
MyThread[] list = new MyThread[100];
for(int i = 0; i < 100; i++){
list[i] = new MyThread();
list[i].start();
} for(int i = 0; i < 100; i++){
list[i].join();
}
/*这里应该如何处理?*/
System.out.println("线程全部执行完毕");
}
创建完最后一个线程开始判断threadList.isEmpty()时,threadList为空,但最后创建的一个
或多个线程还没有执行threadList.add(t),这时就会得出错误结果。
如果将休眠时间设置得较长的话,那么就可以保证在主线程判断threadList.isEmpty()时
threadList不为空。但如果休眠时间较短的话,那么上面的情况就有可能发生。主线程创建完最一个线程后马上执行threadList.isEmpty(),这时最后一个线程可能还在初始化并准备被系统调度执行的阶段,而其他的线程均已执行完毕。在ThreadControl 里面加上一个synchronized的isEmpty方法我觉没用,因为判断isEmpty
只是主线程在做,并不涉及到同步的问题。
当一个子线程结束的时候在notifyAll一下
有朋友说把threadList.isEmpty()套进一个synchronized方法,按照你的思路,因为问题的症结在于ThreadControl.add(This),所以还不如把ThreadControl.add(This)套在一个synchronzied方法中。
但是我认为,上面两个解决办法都是不可行的!!!因为他们都没有避免xjh_Love_paopao()说的这种情况发生!!
但是如果我的程序确实像你说的那样发生了错误,那上面两种办法应该至少可以避免错的发生,因为就像您说的,threadList.isEmpty()不是线程安全的,在检查其是否为空的时候,如果恰好某个线程执行了ThreadControl.add(This),可能会导致错误发生。不知道我理解得对不对?另外请朋友们用“wait - notify ”帮忙改一下我的程序,谢谢!
在100 条线城 执行完后,可以用notiflyall 来恢复线程
还要在println上面加一sleep或者 join 语句
println 执行后 用system.exit(0)退出
因为wait notify() 和 notifyall()方法不同于sleep(),它们要操作对象锁,所以应该放在同步代码快或者同步方法中进行调用。否则程序可能通过编译,但是运行的时候会产生一个IllegalMonitorStateException异常,关于这点,你可以参阅《Java编程思想(3er Edition)》中文版497页。而且也不是子线程调用wait()方法阿。另外我觉得这个问题根本不能用wait() - notify()方法来解决,逻辑上行不通。我是想在前面的所有子线程MyThread结束之后,由主线程来打印一些信息,而wait() - notify()的逻辑是:让某一线程处在等待状态,当外界条件改变时唤醒这个等待的线程。但是我的这个例子好像不太适用吧。如果大家觉得我说的不对,你们帮我改写一下代码,我看看怎么写。
总之 我觉的要实现楼主的要求其实很简单!
class Test extends Thread
{
public static void main(String[] args) throws InterruptedException
{
for(int i=0;i<100;i++)
{
Test test=new Test();
test.start();
}
Thread.sleep(1);
System.out.println("over");
}
public void run()
{
System.out.println(1);
}
}
你们可以看看结果 它打印完所有的1之后 才打印 over!
{
public static void main(String[] args) throws InterruptedException
{
Threads test=new Threads();
for(int i=0;i<100;i++)
{
new Thread(test).start();
}
Thread.sleep(1);
System.out.println("over");
}
}class Threads implements Runnable
{
public void run()
{
System.out.println(1);
}}
两个结果都一样!
我认为是您想简单了。您再好好看看我的代码就明白了。
import java.util.List;public class Test13 { public static void main(String[] args) throws Exception {
List<Thread> list = new ArrayList<Thread>();
for (int i = 0; i < 100; i++) {
Thread worker = new Thread() {
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
worker.start();
list.add(worker);
} /*这里就这么处理*/
for (Thread worker : list) {
worker.join();
} System.out.println("线程全部执行完毕");
}}
我认为您的方法很可能是不安全的。
首先join()方法要放在try块中吧?
我们线程的数目是不固定的,不是简单地100个。
就算是线程数目固定,就是100个。您的程序也会有问题。
因为线程创建后执行start()方法后,不能保证线程立即被执行,所以当创建线程的循环完成后,不一定每个线程都被装进了list中,所以最后的结果不一定准确!
TO rikee19810706():
先创建 100 个线程,然后再一个一个用 join() 去“等”,在你“等”的过程中,前面创建的那一大票线程都在忙着跑呢,这一点跟单线程完全不一样。如果是创建一个就用 join() 去“等”一个,那倒真跟单线程差不多了。 ;)
ThreadClass c1 = new new ThreadClass();
ThreadClass c2 = new new ThreadClass(); Thread t1 = new Thread();
Thread t2 = new Thread();
for(int i = 0,i<10,i++)
{
t1.start;
t2.start;
t1.join();
t2.join();
//.....
sum = num1 + num2 +...........
}
按照楼上的各位意思,sum的求和应该在t1,t2线程终止才进行吧。
可是我在单步调试到第二此循环的时候,就发生异常了:{java.lang.IllegalThreadStateException@1f8}
请问问题在哪里?
{
Thread t1 = new Thread();
Thread t2 = new Thread();
t1.start;
t2.start;
t1.join();
t2.join();
//.....
sum = num1 + num2 +...........
}