创建Java多线程的多种方法ouchuquan

来源:互联网 发布:龙猫头像知乎 编辑:程序博客网 时间:2024/06/05 03:36

前言:编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互。

    概念:

          多进程:面向操作系统的多任务,即一个操作系统运行多个任务。

          多线程:面向程序的多任务,即一个程序运行多个任务。

    创建多线程的方法如下:

    1、通过实现Runnable接口来创建Thread线程:

       其中,Runnable接口(只有一个方法)定义如下:

       

  1. public interface Runnable  
  2. {  
  3.     void run();  
  • }  

 

 

       步骤1:创建实现Runnable接口的类:

       

  1. class SomeRunnable implements Runnable  
  2. {  
  3.     public void run()  
  •     {  
  •       //do something here   
  •     }  
  • }  

 

 

       步骤2:创建一个类对象:

              Runnable oneRunnable = new SomeRunnable();

       步骤3:由Runnable创建一个Thread对象:

              Thread oneThread = new Thread(oneRunnable);

       步骤4:启动线程:

              oneThread.start();

       至此,一个线程就创建完成了。

       注释:线程的执行流程很简单,当执行代码oneThread.start();时,就会执行oneRunnable对象中的void run();方法,

             该方法执行完成后,线程就消亡了。

    2、与方法1类似,通过实现Callable接口来创建Thread线程:

       其中,Callable接口(也只有一个方法)定义如下:

       

  1. public interface Callable<V>  
  2. {  
  3.     V call() throws Exception;  
  • }  

 

步骤1:创建实现Callable接口的类SomeCallable<Integer>(略);

       步骤2:创建一个类对象:

              Callable<Integer> oneCallable = new SomeCallable<Integer>();

       步骤3:由Callable<Integer>创建一个FutureTask<Integer>对象:

              FutureTask<Integer> oneTask = new FutureTask<Integer>(oneCallable);

              注释:FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建,它同时实现了Future和Runnable接口。

       步骤4:由FutureTask<Integer>创建一个Thread对象:

              Thread oneThread = new Thread(oneTask);

       步骤5:启动线程:

              oneThread.start();

       至此,一个线程就创建完成了。

    3、通过继承Thread类来创建一个线程:

       步骤1:定义一个继承Thread类的子类:

      

  1. class SomeThead extends Thraad  
  2. {  
  3.     public void run()  
  •     {  
  •      //do something here   
  •     }  
  • }  

 

 

       步骤2:构造子类的一个对象:

              SomeThread oneThread = new SomeThread();

       步骤3:启动线程:

              oneThread.start();

       至此,一个线程就创建完成了。

       注释:这种创建线程的方法不够好,主要是因为其涉及运行机制问题,影响程序性能。

    4、通过线程池来创建线程:

       步骤1:创建线程池:

              ExecutorService pool = Executors.newCachedThreadPool();

       步骤2:通过Runnable对象或Callable对象将任务提交给ExecutorService对象:

              Future<Integer> submit(Callable<Integer> task);

              注释:Future是一个接口,它的定义如下:

              

  1. public interface Future<T>  
  2. {  
  3.     V get() throws ...;  
  •     V get(long timeout, TimeUnit unit) throws ...;  
  •     void cancle(boolean mayInterrupt);  
  •     boolean isCancelled();  
  •     boolean isDone();  
  • }  

      至此,一个线程就创建完成了。

      注释:线程池需调用shutdown();方法来关闭线程。

   5、通过事件分配线程直接使用程序中的原有线程:

      使用方法:

      直接调用EventQueue类的静态方法invokeLater():

      EventQueue.invokeLater(oneRunnable);

      注释:调用EventQueue.invokeLater(oneRunnable);会直接执行oneRunnable对象中的run()方法。

 

 

常用

 

前言:编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互。

 

    概念:

 

          多进程:面向操作系统的多任务,即一个操作系统运行多个任务。

 

          多线程:面向程序的多任务,即一个程序运行多个任务。

 

    创建多线程的方法如下:

 

    1、通过实现Runnable接口来创建Thread线程:

 

       其中,Runnable接口(只有一个方法)定义如下:

 

       
[java] view plaincopyprint?
01.public interface Runnable  
02.{  
03.    void run();  
04.}  
public interface Runnable
{
    void run();
}

 

       步骤1:创建实现Runnable接口的类:

 

       
[java] view plaincopyprint?
01.class SomeRunnable implements Runnable  
02.{  
03.    public void run()  
04.    {  
05.      //do something here   
06.    }  
07.}  
class SomeRunnable implements Runnable
{
    public void run()
    {
      //do something here
    }
}

 

       步骤2:创建一个类对象:

 

              Runnable oneRunnable = new SomeRunnable();

 

       步骤3:由Runnable创建一个Thread对象:

 

              Thread oneThread = new Thread(oneRunnable);

 

       步骤4:启动线程:

 

              oneThread.start();

 

       至此,一个线程就创建完成了。

 

       注释:线程的执行流程很简单,当执行代码oneThread.start();时,就会执行oneRunnable对象中的void run();方法,

 

             该方法执行完成后,线程就消亡了。

 

    2、与方法1类似,通过实现Callable接口来创建Thread线程:

 

       其中,Callable接口(也只有一个方法)定义如下:

 

       [java] view plaincopyprint?01.public interface Callable<V>  02.{  03.    V call() throws Exception;  04.}  public interface Callable<V>
{
    V call() throws Exception;
}

 

       步骤1:创建实现Callable接口的类SomeCallable<Integer>(略);

 

       步骤2:创建一个类对象:

 

              Callable<Integer> oneCallable = new SomeCallable<Integer>();

 

       步骤3:由Callable<Integer>创建一个FutureTask<Integer>对象:

 

              FutureTask<Integer> oneTask = new FutureTask<Integer>(oneCallable);

 

              注释:FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建,它同时实现了Future和Runnable接口。

 

       步骤4:由FutureTask<Integer>创建一个Thread对象:

 

              Thread oneThread = new Thread(oneTask);

 

       步骤5:启动线程:

 

              oneThread.start();

 

       至此,一个线程就创建完成了。

 

    3、通过继承Thread类来创建一个线程:

 

       步骤1:定义一个继承Thread类的子类:

 

       
[java] view plaincopyprint?
01.class SomeThead extends Thraad  
02.{  
03.    public void run()  
04.    {  
05.     //do something here   
06.    }  
07.}  
class SomeThead extends Thraad
{
    public void run()
    {
     //do something here
    }
}

 

       步骤2:构造子类的一个对象:

 

              SomeThread oneThread = new SomeThread();

 

       步骤3:启动线程:

 

              oneThread.start();

 

       至此,一个线程就创建完成了。

 

       注释:这种创建线程的方法不够好,主要是因为其涉及运行机制问题,影响程序性能。

 

    4、通过线程池来创建线程:

 

       步骤1:创建线程池:

 

              ExecutorService pool = Executors.newCachedThreadPool();

 

       步骤2:通过Runnable对象或Callable对象将任务提交给ExecutorService对象:

 

              Future<Integer> submit(Callable<Integer> task);

 

              注释:Future是一个接口,它的定义如下:

 

              
[java] view plaincopyprint?
01.public interface Future<T>  
02.{  
03.    V get() throws ...;  
04.    V get(long timeout, TimeUnit unit) throws ...;  
05.    void cancle(boolean mayInterrupt);  
06.    boolean isCancelled();  
07.    boolean isDone();  
08.}  
public interface Future<T>
{
    V get() throws ...;
    V get(long timeout, TimeUnit unit) throws ...;
    void cancle(boolean mayInterrupt);
    boolean isCancelled();
    boolean isDone();
}

 

      至此,一个线程就创建完成了。

 

      注释:线程池需调用shutdown();方法来关闭线程。

 

   5、通过事件分配线程直接使用程序中的原有线程:

 

      使用方法:

 

      直接调用EventQueue类的静态方法invokeLater():

 

      EventQueue.invokeLater(oneRunnable);

 

      注释:调用EventQueue.invokeLater(oneRunnable);会直接执行oneRunnable对象中的run()方法。

 

三、两种创建线程方式的比较 
采用继承Thread类方式: 
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。 
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。

采用实现Runnable接口方式: 
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标(target)对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。


(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。

 

提示:在实际开发中,一般采用实现Runnable接口的方式来创建线程类,因为它具有更好的灵活性和可扩展性。

3)第三种方法是以匿名内部类的方式创建,

内部类也可以,不必匿名.

即可以在一个方法中创建线程,当 方法被调用时,线程即启动,这在编写一些简单线程应用时十分方便,如swing事件中处理 一个可能时间较长的任务,使用这种方法就不致于阻塞用户界面的操作。

public class ThreadTest { 
     //程序主方法 
      public static void main(String args[]){ 
            ThreadTest tt =  new ThreadTest(); 
            for(int i=0;i<10;i++){ 
                  tt.strartMyThread(i); 
             } 
      }

      /** 
       * 这个方法会启动一个匿名线程线程 
       */ 
      public void strartMyThread(int threadID) { 
            //要传入匿名线程内使用的参数必须定义为final型 
            final int id=threadID; 
            Runnable runner = new Runnable() { 
                  public void run(){ 
                         int i=10; 
                        boolean flag=true; 
                        while(flag){ 
                                try{ 
                            Thread.sleep(3000); 
                            //在匿名线程类调用类中的其它方法 
                            otherMethod(id); 
                               if(i>13){ 
                                      flag=false; 
                             } 
                             }catch(Exception ef){} 
                       } 
                  } 
            }; 
            //最后,启动这个内部线程 
            Thread t = new Thread(runner); 
            t.start(); 
      } 
      //测试方法 
      private void otherMethod(int i){ 
            System.out.println("可以直接调用类中的其它方法: "+i); 
      } 
}

在程序中使用匿名内部类创建线程十分方便:在一个方法调用中就可以启动一个线程,而 
且这个线程还可以直接调用类中的属性和方法;特别注意的是,在方法中启动匿名内部线程 
时,如要向这个线程的 run 方法内传递参数,在创建方法中这个参数必须定义为 final 类型, 
如上代码中的

//要传入匿名线程内使用的参数必须定义为final型 
            final int id=threadID;

 

0 0
原创粉丝点击