不用多线程。可能吗!!!,就算API提供有什么接口也会是遵循多线程原理。

解决方案 »

  1.   

    可以不需要多线程,我的意思是不需要你写多线程线程,但实际上你必须使用线程的东西。
    比如你有一个非常长的循环,你可以在每次循环的时候加一个 Thread.sleep(100)
    给一100毫秒让你的循环休息,让界面重绘或者是干其它的事情。
      

  2.   

    在事件处理中,就算用sleep使循环休息,也没用,因为主线程阻塞在事件处理中,无法响应其他事件。
      

  3.   

    肯定要通过多线程解决的。上面Thread.sleep(100)也是这样的。
      

  4.   

    youyue(由月) 说的对,因为主线程被堵塞了,界面就像死掉一样
    但是如果主线程如果是被模式对话框堵塞的话,界面确实是没有死掉这就是我不明白的地方,我猜想界面和主线程可能是两个线程
    其实无论是Swing,AWT还是MFC,这个道理应该是一样的希望这方面的牛人可以解释一下:)
      

  5.   

    我说的不用多线程是指不用自己做线程
    至于Swing真正怎么实现的,那不关心
      

  6.   

    1,为什么在等待模式对话框,或者提示框返回的过程中,界面不会死
    这个对话框在java里面不是就是1个新的线程?主界面当然不会死咯
    你如果不用对话框。。那么就是在1个线程里面。。当然需要等程序计算完成才可以处理这个线程就是主界面的操作。。主界面在处理的时候就会死了2,如果我有一个处理逻辑时间很长,我希望在等待处理的时候界面也不死,不能获取焦点和事件没有关系,应该怎么做?不要告诉我多线程,这个我会做。
    最好还是开线程,不行就开个dialog把。。哈哈。。不要setVisible(true)也可以但是线程很简单的。。只要extends Thread就ok。。+个run方法,用的时候是.start()
      

  7.   

    1,为什么在等待模式对话框,或者提示框返回的过程中,界面不会死
    这个对话框在java里面不是就是1个新的线程?主界面当然不会死咯
    你如果不用对话框。。那么就是在1个线程里面。。当然需要等程序计算完成才可以处理这个线程就是主界面的操作。。主界面在处理的时候就会死了呵呵,如果对话框是一个新的线程的话,那么为什么主线程还需要等这个线程返回才往下走?
    还有关键的问题不在这里,而在于主线程被堵塞了为什么界面还能不死
    2,如果我有一个处理逻辑时间很长,我希望在等待处理的时候界面也不死,不能获取焦点和事件没有关系,应该怎么做?不要告诉我多线程,这个我会做。
    最好还是开线程,不行就开个dialog把。。哈哈。。不要setVisible(true)也可以但是线程很简单的。。只要extends Thread就ok。。+个run方法,用的时候是.start()等于没有说
      

  8.   

    给楼主提个意见:学东西多问几个为什么是好的,但也不要钻牛角尖。java的gui如何实现模式对话框,是底层的东西,对我们来说是透明的,它到底用的什么原理我们并不需要知道,也没必要知道;在事件处理时间很长的情况下,我所看过的所有书籍和资料中都只教我们使用多线程,实在没见过其他方法。我觉得你这样问有点钻牛角尖,就好像是问“怎样才能让我这台机器运行?别告诉我说要安装cpu,这我知道”一样。
      

  9.   

    to youyue(由月),谢谢,但是如果有人可以没有CPU就可以让机器运行的话我想我还是会请教一下是怎么运行的。
      

  10.   

    凡事都要追问到底,也得看什么事.不要忘了为什么要追问到底.是想成为swing高手还是java高手还是编程高手还是软件高手
      

  11.   

    难道是:SwingUtilities.invokeAndWait ... ?
      

  12.   

    你的问题问得很含糊,或者是我理解能力差吧。首先你第一个问题,弹出一个对话框,如果你没另外写成线程启动只是单纯地在主线程main中show一个Dilog出来的话,那它只是在主线程下的代码,那种等待是代码运行逻辑的,就好比非界面的等待用户输入。
    问题2,首先,界面是不会“死”的,只是失去Cpu资源或者有内存交换而失去效果。你要后台执行Cpu运行时占用久的程序,正如我上面的说明,关键在于Cpu的占用。多线程是个比较好的选择,GUI本身就有AWT的本地线程维护,你可以为你的处理逻辑时间很长的代码用线程去执行,并处理好主线程和它的关系,由于你问得那么抽象,我回答也只能到这地步,有错请指正,愿受教。
      

  13.   

    ok,我举一个例子,比如我在程序中需要用户确认下一步的操作,当然我可以很简单的调用一下JOptionPane的方法探出一个对话框(或者自己做一个模式对话框),然后等待用户的选择,这个时候整个界面也可以正常的显示,但是注意到实际上主线程也是停在这里了,要直到用户选择才可以接着往下运行,这是关键问题。现在我要实现的是也是需要用户确认一下,但是这个确认过程可能很长(比如我需要去访问一个远程机器,比方说需要10S,当然这个可能是网络的问题,但是可以通过资源管理器看到,并没有占用太多的CPU资源),那么这个10S中界面就是处于没有反应的状态。我就是想知道为什么同样主线程是在等待的情况下,一个会死一个不会死,实际上,第2种情况并不是和机器的CPU相关的,无论你多好的机器,程序也没有占用太多的资源的情况下。应该是因为主线程被占用导致的。至于怎么解决这个问题,我不想讨论,大家都知道用多线程(实际上我也是这么做的)。
      

  14.   

    你有让CPU处理不完的业务逻辑控制吗?如果这样的话,公司是要你想办法解决这个业务逻辑控制的,解决不了的话,哈哈,你就得走人了。
      

  15.   

    那我的建议是你最好运行时看着资源管理器,看看CPU占用,如果不是占满,然后,看看是否网络连接操作,因为硬件机制会影响底层,也不是的话,用Debug的IDE单步执行,直到你程序Halt的代码段,以及观察一下你AWT相关的线程运作如何。
      

  16.   

    Dark
    你可以随便写个程序,在button的触发事件中加上
    try{
    Thread.sleep(100000);
    }catch(Exception e){}看看你的窗口是不是死掉了,再看看资源管理器我再说一遍,是因为主线程被占用而不是资源的问题
      

  17.   

    一个Swing制作欢迎屏幕的例子,大家可以参考一下,代码如下
    [例子是从网上改的]:
    --------------------------------------------------------------
    /*
     * Created on 2004-10-19
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package splash;import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;/**
     * @author NetSniffer
     * 
     * TODO To change the template for this generated type comment go to Window -
     * Preferences - Java - Code Style - Code Templates
     */class SplashWindow extends JWindow {
        public SplashWindow(String filename, Frame f, int waitTime) {
            super(f);
            JLabel l = new JLabel(new ImageIcon(filename));
            getContentPane().add(l, BorderLayout.CENTER);
            pack();
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            Dimension labelSize = l.getPreferredSize();
            setLocation(screenSize.width / 2 - (labelSize.width / 2),
                    screenSize.height / 2 - (labelSize.height / 2));
            addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    setVisible(false);
                    dispose();
                }
            });
            final int pause = waitTime;
            final Runnable closerRunner = new Runnable() {
                public void run() {
                    setVisible(false);
                    dispose();
                }
            };
            Runnable waitRunner = new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(pause);
                        SwingUtilities.invokeAndWait(closerRunner);
                    } catch (Exception e) {
                        e.printStackTrace();
                        // 能够捕获InvocationTargetException
                        // 能够捕获InterruptedException
                    }
                }
            };
            setVisible(true);
            Thread splashThread = new Thread(waitRunner, "SplashThread");
            splashThread.start();
        }
        public static void main(String[] args) {
            Frame f=new Frame("SPLASH WINDOW");
            f.setSize(new Dimension(400,300));
            f.addWindowListener(new WindowAdapter(){
             public void windowClosing(WindowEvent e){
             System.exit(0);
             }
            });
            f.setLayout(new BorderLayout());
            f.add(new Button("SPLASH WINDOW"),BorderLayout.CENTER);
            f.setVisible(true);
            new SplashWindow("splash.jpg",f,2000);
        }
    }
    -----------------------------------------------------------------
    原作者的解释:
    [
    这里的基本思路是利用一个在一定时间内暂停等待的Thread对象。在上面的代码中,线程的暂停时间是2秒。当这个线程唤醒时,它将关闭欢迎屏幕。由于Swing是非线程安全的,除非代码在事件分派线程上执行,否则它就不应该影响任何UI组件的状态。所谓事件分派线程,就是Swing中负责绘图和事件处理的线程。为了解决这个问题,Swing设计者赋予我们安全地把Runnable对象加入UI事件队列的能力。在本例中,我们用可运行对象closerRunner完成最关键的工作。我们把可运行对象传入SwingUtilities.invokeAndWait()静态方法,然后SwingUtilities.invokeAndWait()进行所有未完成的UI操作,并执行传递给该方法的可运行对象closerRunner的run方法。通过运用一个独立的线程负责欢迎屏幕的关闭操作,应用担负起了显示和关闭欢迎屏幕之间的所有操作。如果要让欢迎屏幕总是显示且用户不能关闭它,你必须删除那些隐藏欢迎屏幕的代码。如果要让欢迎屏幕只能由用户手工关闭,你可以象使用任何其他JWindow对象一样调用SplashWindow3对象上的setVisible(false)和dispose()方法。
    ]