请教一下 在JAVA中 线程的意思??用法??处在什么地方  可以起到什么作用??请说下详细解释??最好做出例子说明!!一定给分...

解决方案 »

  1.   

     1、谁创建线程? 
      
      
      即使您从未显式地创建一个新线程,您仍可能会发现自己在使用线程。线程被从各种来源中引入到我们的程序中。 
      
      有许多工具可以为您创建线程,如果要使用这些工具,应该了解线程如何交互,以及如何防止线程互相干扰。 
      
      2、AWT 和 Swing 
      
      
      任何使用 AWT 或 Swing 的程序都必须处理线程。AWT 工具箱创建单个线程,用于处理 UI 事件,任何由 AWT 事件调用的事件侦听器都在 AWT 事件线程中执行。 
      
      您不仅必须关心同步对事件侦听器和其它线程之间共享的数据项的访问,而且还必须找到一种方法,让由事件侦听器触发的长时间运行任务(如在大文档中检查拼写或在文件系统中搜索一个文件) 在后台线程中运行,这样当该任务运行时,UI 就不会停滞了(这可能还会阻止用户取消操作)。这样做的一个好的框架示例是 SwingWorker 类
      AWT 事件线程并不是守护程序线程;这就是通常使用 System.exit() 结束 AWT 和 Swing 应用程序的原因。 
      
      
      3、使用 TimerTask 
      
      
      JDK 1.3 中,TimerTask 工具被引入到 Java 语言。这个便利的工具让您可以稍后在某个时间执行任务(例如,即从现在起十秒后运行一次任务),或者定期执行任务(即,每隔十秒运行任务)。 
      
      实现 Timer 类非常简单:它创建一个计时器线程,并且构建一个按执行时间排序的等待事件队列。 
      
      TimerTask 线程被标记成守护程序线程,这样它就不会阻止程序退出。 
      
      因为计时器事件是在计时器线程中执行,所以必须确保正确同步了针对计时器任务中使用的任何数据项的访问。 
      
      在 CalculatePrimes 示例中,并没有让主线程休眠,我们可以使用 TimerTask,方法如下:
      
      
       public static void main(String[] args) {
       Timer timer = new Timer();
       
       final CalculatePrimes calculator = new CalculatePrimes();
       calculator.start();
      
       timer.schedule(
       new TimerTask() {
       public void run()
       {
       calculator.finished = true;
       }
       }, TEN_SECONDS);
       }
       
      4、servlet 和 JavaServer Pages 技术 
      
      
      servlet 容器创建多个线程,在这些线程中执行 servlet 请求。作为 servlet 编写者,您不知道(也不应该知道)您的请求会在什么线程中执行;如果同时有多个对相同 URL 的请求入站,那么同一个 servlet 可能会同时在多个线程中是活动的。 
      
      当编写 servlet 或 JavaServer Pages (JSP) 文件时,必须始终假设可以在多个线程中并发地执行同一个 servlet 或 JSP 文件。必须适当同步 servlet 或 JSP 文件访问的任何共享数据;这包括 servlet 对象本身的字段。 
      
      
      5、实现 RMI 对象 
      
      
      RMI 工具可以让您调用对在其它 JVM 中运行的对象进行的操作。当调用远程方法时,RMI 编译器创建的 RMI 存根会打包方法参数,并通过网络将它们发送到远程系统,然后远程系统会将它们解包并调用远程方法。 
      
      假设您创建了一个 RMI 对象,并将它注册到 RMI 注册表或者 Java 命名和目录接口(Java Naming and Directory Interface (JNDI))名称空间。当远程客户机调用其中的一个方法时,该方法会在什么线程中执行呢? 
      
      实现 RMI 对象的常用方法是继承 UnicastRemoteObject。在构造 UnicastRemoteObject 时,会初始化用于分派远程方法调用的基础结构。这包括用于接收远程调用请求的套接字侦听器,和一个或多个执行远程请求的线程。 
      
      所以,当接收到执行 RMI 方法的请求时,这些方法将在 RMI 管理的线程中执行。 一般的,如果多个线程协作存、取某个变量时,一般需要用到synchronized关键字进行同步操作,如: 
    public class MyTestThread extends MyTest implements Runnable { 
    private boolean _done = false; 
    public synchronized boolean getDone() 

    return _done; 

    public synchronized void setDone(boolean b) 

    _done = b; 
    } public void run( ) { 
    boolean done; 
    done = getDone(); 
    while (!done) { 
    repaint( ); 
    try { 
    Thread.sleep(100); 
    } catch (InterruptedException ie) { 
    return; 




    或者: 
    public class MyTestThread extends MyTest implements Runnable { 
    private boolean _done = false; 
    public void setDone(boolean b) 

    synchronized(this) 

    _done = b; 

    } public void run( ) { 
    boolean done; 
    synchronized(this) 

    done = _done; 
    } while (!done) { 
    repaint( ); 
    try { 
    Thread.sleep(100); 
    } catch (InterruptedException ie) { 
    return; 




    但是,通过volatile关键字,我们可以大大简化: 
    public class MyTestThread extends MyTest implements Runnable { 
    private volatile boolean done = false; 
    public void run( ) { 
    while (!done) { 
    repaint( ); 
    try { 
    Thread.sleep(100); 
    } catch (InterruptedException ie) { 
    return; 



    public void setDone(boolean b) { 
    done = b; 


    volatile只是声明变量被拒绝优化而已也就是说使得存取变量变为了原子操作(atom operation) 你上面的最后一段代码可以正确的在单CPU上运行但是如果在多CPU计算机上(甚至是现在的多核CPU上)就会发生操作,因为即使是原子操作也只是针对单个CPU无法被打断而已但是对于多个并行的CPU还是会发生错误但是上面的两段代码却可以正确的在多CPU环境被运行 
      

  2.   

    这里有例子,自己看,不过是英文的,我觉得不错,http://apicode.gicp.net/
      

  3.   

    嗯,但有一点我觉得CPU在单线程时不能满负荷运转,这样就可以通过多线程方法利用多余的运能增加效率,否则多线程也无法提高效率,理论上还是降低的
      

  4.   

    想用就用背,通常业务逻辑复杂的,都会用到。
    在NIO下载中也会要用到。