zoukankan      html  css  js  c++  java
  • 创建Java多线程的多种方法ouchuquan

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

        概念:

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

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

        创建多线程的方法如下:

        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;

  • 相关阅读:
    4.单例模式
    3.适配器模式
    2.策略模式
    1.工厂模式
    机器学习
    何为技术领导力
    图像像素的算术操作
    图像对象创建和赋值的区别
    图像色彩空间转换
    notepad更改文档编码格式
  • 原文地址:https://www.cnblogs.com/langtianya/p/2664218.html
Copyright © 2011-2022 走看看