zoukankan      html  css  js  c++  java
  • 多线程基础之创建线程的三种方式

      在java平台中创建线程就是创建一个Thread类或者其子类的实例。每个线程的任务处理逻辑都在run()方法中实现,它在java虚拟机中由相应的线程直接调用。

      运行一个线程就是让java虚拟机执行该线程的run()方法。

      启动线程需要调用Thread类的strat()方法。

     下面代码实现创建线程.

    继承Thread类

        

    public class ThreadApp01 {
    	
    	public static void main(String[] args) {
    		Thread myThread = new MyThread();
    		myThread.start();
    
    	}
    	
    }
    	
    	class MyThread extends Thread {
    		@Override
    		public void run() {
    			System.out.println("继承Thread类");
    		}
    		
    	}
    		
    	}

     

    实现Runable接口

        

    public class ThreadApp02 {
        
        public static void main(String[] args) {
            Thread myThread2 = new Thread(new MyThread2());
            myThread2.start();
        }
        
    }
        
        class MyThread2 implements Runnable{
    
            @Override
            public void run() {
                System.out.println("实现Runable接口");
                
            }
            
        }

     

    通过Callable和FutureTask创建线程

        a. 创建Callable接口的实现类,并实现call()方法;
        b. 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callback对象的call()方法的返回值;
        c. 使用FutureTask对象作为Thread对象的target创建并启动新线程;

        d. 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。

    public class CallableThreadTest implements Callable<Integer>  
    {  
      
        public static void main(String[] args)  
        {  
            CallableThreadTest ctt = new CallableThreadTest();  
            FutureTask<Integer> ft = new FutureTask<Integer>(ctt);  
    //        Thread thread = new Thread(ft,"有返回值的线程");
    //        thread.start();
            for(int i = 0;i < 100;i++)  
            {  
                System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i);  
                if(i==20)  
                {  
                    new Thread(ft,"有返回值的线程").start();  
                }  
            }  
            try  
            {  
                System.out.println("子线程的返回值:"+ft.get());  
            } catch (InterruptedException e)  
            {  
                e.printStackTrace();  
            } catch (ExecutionException e)  
            {  
                e.printStackTrace();  
            }  
      
        }  
      
        @Override  
        public Integer call() throws Exception  
        {  
            int i = 0;  
            for(;i<100;i++)  
            {  
                System.out.println(Thread.currentThread().getName()+" "+i);  
            }  
            return i;  
        }  
      
    }  

    不管是哪种方式,当该线程的run方法执行时,线程就结束,所占的资源会被垃圾回收器回收。我们不能通过start方法再一次调用,否则会抛出IllegalThreadExcepton异常.

     一个线程就是一个对象,创建时会为其分配内存空间,JAVA平台的线程还会为其创建一个内核线程,相对来说成本较高。

    三种创建方式的区别:

       第二种和第三种基本很类似,只是实现callable可以有返回值。

       从面向对象编程角度:第一种是一种基于继承(Inheritance)的技术。第二,三种是一种基于(Composition)的技术,由于组合相对继承来说,类与类之间的耦合程度较低,更灵活.

          从对象共享的角度:第二种方式可能导致多个线程实例共享一个Runable实例,可能涉及一些线程安全方面的因素.

       从对象创建成本 : 创建一个线程实例比创建一个Runable实例成本相对来说高.

  • 相关阅读:
    利用canvas的getImageData()方法制作《在线取色器》
    JS的click触发匿名函数 怎么解绑
    apache配置VirtualHost(windows)
    Docker容器化【Dockerfile编写&&搭建与使用Docker私有仓库】
    17.持续集成与容器管理
    第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第十二天】(系统架构讲解、nginx)
    springMVC常用知识点的整理
    第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第十一天】(购物车+订单)
    第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第十天】(单点登录系统实现)
    第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第九天】(商品详情页面实现)
  • 原文地址:https://www.cnblogs.com/goxcheer/p/9291708.html
Copyright © 2011-2022 走看看