多线程基础之创建线程的三种方式

  在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实例成本相对来说高.

原文地址:https://www.cnblogs.com/goxcheer/p/9291708.html