本帖最后由 zyw745293 于 2009-06-17 10:58:08 编辑

解决方案 »

  1.   

     machine1.setPriority(1); 你设置下他们的优先级,在看看。
      

  2.   

    在if语句快后面加上一句打印的 你就知道怎么回事了 比如:System.out.println("执行");
      

  3.   

    我照你说的做了,把原代码if语句块修改为if(++count%10==0){
    log.append("\n");
    System.out.println("执行");
    }但现在其中一个结果如下(每次运行结果是不一样的), m2线程并没有执行. 而且"执行"并没按照我设置的每count%10才打印.
    main
    5
    5
    5
    执行
    m1:0 m1:1 m1:2 m1:3 m1:4 m1:5 m1:6 m1:7 m1:8 m1:9 执行
    执行
    执行
      

  4.   

    楼主理解错了,main方法里的print不一定是在最后执行,所以不会打印最终结果
    你在for循环后加上
    System.out.println(log);
    看看就知道了
      

  5.   

    线程基础...
    线程的运行顺序不可预知...
    你自己看你的程序啊..
    你开了两个子线程,这两个线程调用start方法后,并不是马上运行的
    线程的运行还要依赖于进程分配,实际上,线程启动更复杂,包含了资源分配,内存分配等等,这些动作都需要CPU时间的
    而main进程不管你的进程是不是在运行,它自己管自己的运行,很有可能在你log还没有并两个子线程写入的时候已经被打印了,当然什么东西都没有了
      

  6.   

    如果不对线程进行控制,线程运行顺序是不可预测的。就算做操作也只能进行大概的预测不能精确。
    main方法执行完后你的程序就退出了。当然那两个线程就得不到执行机会,你要把它设置成demo的线程。为什么log没有打印,不知道有没有人解答下?这个我不太清楚。。
      

  7.   

    setDaemon(boolean on)
    打错方法了。
    呵呵。不好意思。
      

  8.   


    在线程还没有执行之前,这行语句就已经执行过了。所以打印log时log里还没有内容,而不是没有打印。
      

  9.   

    楼主我试验了下。
    设置打Daemon线程也不行.
    hehe 
      

  10.   

    因为你启动线程的时候run方法还没完成 所以会先调用 main()中的其他方法
              System.out.println(main.getName()); 
             System.out.println(main.getPriority());
             System.out.println(machine1.getPriority());
             System.out.println(machine2.getPriority());
             System.out.println(log);
    这些会先执行因为log是空的所以不会打印出东西
         public void run(){
            for(int a = 0;     a<20;a++){
                log.append(currentThread().getName()+":"+a+" ");
                if(++count%10==0){
                    log.append("\n");
                }
            }
        System.out.println(log);
        }
    把打印语句放到run方法中这样就可以看到效果了
      

  11.   

    设置优先级是起不到作用的,如果你其它线程耗的时间比较长,主线程很快就执行完了的话,可以采用在主线程使用wait等待,然后在子线程执行完的时候调用notify唤醒主线程。
      

  12.   

    你想交电脑界朋友嘛~我虽说称不上高手,但是对电脑的工作了如指掌,有空的朋友看看这个问题,我已经解决了,电脑开不开机,主机回转。但是显示器不会显示。http://net-ke.cn/0_5_101553.aspx
      

  13.   

    楼主的理解是对的,主线程(其实是进程)挂了,别的线程很可能没机会继续.
    所以你在主线程退出前,需要wait
      

  14.   

    楼主的理解是对的,主线程(其实是进程)挂了,别的线程很可能没机会开始.
    所以你在主线程退出前,需要wait,等待别的结束的信号过来后才能结束.
      

  15.   

    其实我们是可以控制主线程的运行顺序的,JAVA本身提供了这个控制机制。只要我们在
    machine1.start();
    machine2.start();
    这两句话后面追加:
    machine1.join();
    machine2.join();
    这两句话,那么主线程就会等待子线程运行完毕才会运行了。这是我们在编程中经常使用的
    控制方式^_^
      

  16.   

    其实楼主要的答案很简单:程序在所有的非Daemon线程结束后终止。
    楼主之所以没有看到期望的打印结果,是因为main线程终止时,machine1/2还没来得及执行,不过在程序终止前终归是要执行的。(另外,多运行几次,有时能看到预期结果)
    我改了下程序:
    public class Machine extends Thread
    {
        // private static StringBuffer log = new StringBuffer();    private static int count = 0;    public void run()
        {
            StringBuffer log = new StringBuffer();
            for (int a = 0; a < 20; a++)
            {
                log.append(currentThread().getName() + ":" + a + " ");
                if (++count % 10 == 0)
                {
                    log.append("\n");
                }        }
            System.out.println(log);
        }    public static void main(final String[] args)
        {
            Thread main = Thread.currentThread();
            System.out.println(main.getName());
            Machine machine1 = new Machine();
            Machine machine2 = new Machine();
            machine1.setDaemon(false);// 强调一下,默认就是false
            machine2.setDaemon(false);
            machine1.setName("m1");
            machine2.setName("m2");
            machine1.start();
            machine2.start();        // try
            // {
            // Thread.sleep(2000);
            // }
            // catch (Exception e)
            // {
            // e.printStackTrace();
            // }       System.out.println(main.getPriority());// 打印主线程优先级
            System.out.println(machine1.getPriority());// 打印m1线程优先级
            System.out.println(machine2.getPriority());// 打印m2线程优先级    }
    }
      

  17.   

    可以通过判断线程状态 所有线程都已运行 再结束mainfor(int i=0;i<count;i++){
    if(parseThread[i].getState().name().equals("WAITING")){
    Thread.sleep(50);
    i--;
    }
    }
      

  18.   

    cpu问题  关键不知道线程什么时候才能执行
      

  19.   


    public class Machine extends Thread{
        private static StringBuffer log = new StringBuffer();
        private static int count = 0 ;
        
        public void run(){
            for(int a = 0;     a<20;a++){
                log.append(currentThread().getName()+":"+a+" ");
                if(++count%10==0){
                    log.append("\n");
                }
            }
        }
        
        public static void main(String[] args) {
            Thread main = Thread.currentThread();
            System.out.println(main.getName());
            Machine machine1 = new Machine();
            Machine machine2 = new Machine();
            machine1.setName("m1");
            machine2.setName("m2");
            machine1.start();
            machine2.start();
            /* try {
                Thread.sleep(2000);    
            } catch (Exception e) {
                e.printStackTrace();
            }
            */
            try {
        machine1.join();//等待m1线程结束
        machine2.join();//等待m2线程结束,主线程继续向下执行
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
              System.out.println(main.getPriority());//打印主线程优先级
             System.out.println(machine1.getPriority());//打印m1线程优先级
             System.out.println(machine2.getPriority());//打印m2线程优先级   
             System.out.println(log);
        }
    }
    main
    5
    5
    5
    m2:0 m1:0 m2:1 m1:1 m2:2 m1:2 m2:3 m1:3 m2:4 m1:4 
    m2:5 m1:5 m2:6 m1:6 m2:7 m1:7 m2:8 m1:8 m2:9 m1:9
    m2:10 m1:10 m2:11 m2:12 m1:11 m2:13 m1:12 m2:14 m1:13 m2:15 
    m1:14 m2:16 m1:15 m2:17 m1:16 m2:18 m1:17 m2:19 m1:18 m1:19 
    如果不等待子线程结束,很有可能在主线程执行完System.out.println(log);后还没向log写入,
    或者只写入了一部分,主要是没对3个线程的进度进行控制引起的,所以上面的输出顺序每次都
    有可能不同。另外,即使没有machine1.join();语句,主线程也会在执行完自己的任务后等待
    子线程结束之后再退出,不会存在来不及执行的情况
      

  20.   

    这个问题应该和Daemon没有关系。虚拟机规范规定虚拟机推出的前提是所有非daemon线程退出。这里main,m1,m2都是非daemon线程,所以虚拟机一定会等他们退出的。
    如果把这个程序稍微做一点修改,把run()里的log改成 System.out.print,那么可以看到,m1和m2总是会打印的。
        public void run() {
            for (int a = 0; a < 20; a++) {
                System.out.print(currentThread().getName() + ":" + a + " ");
                //log.append(currentThread().getName() + ":" + a + " ");
                if (++count % 10 == 0) {
                    System.out.println();
                    //  log.append("\n");
                }
            }
        }那么问题出在哪里呢?看样子是log的问题了。
    实例log是StringBuffer类型的,那么这个程序作了什么呢?
    log是一个StringBuffer类型的一个static变量,在多个线程中间都可以被操作。m1和m2做的事情是append 往log里追加内容,但这些内容直到main线程退出之前最后一行才打印,因为log不是被同步的,所以main退出的时候m1和m2还没来得及往log里写内容,所以这个时候log是空的,实际上确实是打印了,只是内容是空的。m1和m2等main退出后呢,也确实给log追加内容了,但只是没有打印而已。
      

  21.   

    问题:
    以上代码中创建了m1、m2线程,还有本身的线程main,为什么使用了try代码块中的主线程休眠才可以看到m1、m2执行run()方法的结果?而将try block注释掉之后m1、m2的run()似乎没怎么执行。  个人理解似乎是main主线程急于结束,没能给m1、m2线程执行的机会。但按道理应该是m1、m2并发执行,main()也不应该干涉它们的执行啊。 请高手指教?答案:
    你说的有道理,你的程序确实创建了三个非deamon线程,且互不干扰。没有结果输出的主要原因是:
    1.JVM从main方法开始执行,这是主线程。
    2.同时创建了两个线程m1,m2并启动线程,在启动过程中有JVM调度到就绪队列中等待CPU的分配。
    3.主线程继续往下执行,由于线程的调度是需要时间的。m1,m2线程还没执行完,主线程就执行了打印操作。
    4.所以你最终看到的结果是还没执行完的结果。
      

  22.   

    37楼正解,楼主不妨把打印语句写在run方法里看下就知道了。
      

  23.   


    正确,执行 System.out.println(log);的时候log还没有东西
      

  24.   

    楼主的验证方法有问题,因为log有可能为空,因为main早于另外两个线程执行
      

  25.   

    楼上你还关注啥啊,已经有正确答案了,就是join,前面代码都有啦
      

  26.   

           主线程中只是负责启动了两个子线程,并不负责将两个子线程都运行结束自己才结束。也就是说,两个子线程还没有启动运行时,那句println(log)已经走过去了,此时的log啥都没有,当然打印结果也是啥都没有喽。应该将println() 写到子线程重写的run方法里面去。
      

  27.   

    楼上说得比较全了,
    log确实被打印了,通过这种方式可以看到现象
    System.out.println(main.getPriority());// 打印主线程优先级
    System.out.println(machine1.getPriority());// 打印m1线程优先级
    System.out.println(machine2.getPriority());// 打印m2线程优先级
    System.out.println(log);
    System.out.println("结束");
    结果是:
    5
    5
    5结束明显有个回行,说明log被打印了,只是log为空而已!我的想法是:当执行main是创建主线程,执行期间又创建两个线程m1,m2,并且m1,m2开始等待cup调度运行,此时主线程继续向下运行,直接打印log,所以m1,m2未来及时更新log的内容,之后更新完也不能再打印!!!