线程的创建方式

本文详细比较了Java中通过继承Thread类、实现Runnable接口和实现Callable接口启动多线程的方法,重点讲解了Runnable接口的使用优势,并介绍了Callable接口的返回值和异常处理特性。
摘要由CSDN通过智能技术生成

一:继承Thread类

         1:重写run()方法
         2:创建类对象并调用start()方法,即可启用多线程

通过继承Thread类的类,实例化一个类对象,再通过这个(子)类对象调用Thread类(父)中的start方法.

package thread;

/**
  * 开启多线程的方法一----继承Thread类:
 * 1:重写run()方法
 * 2:创建类对象并调用start()方法,即可启用多线程
 *
 */

public class Demo01 extends Thread
{
	public void run() 
	{
		super.run();//run方法线程体
		for(int i= 0;i<20;i++)
		{
			System.out.println("线程1----"+i);
		}
	}
	public static void main(String[] args)
	{
		//因为CPU处理速度过快,i设置大时才能看出这是多线程并发执行
		//线程也不一定立刻执行,而是由CPU调度决定处理的顺序,但一定是并发执行
		Demo01 demo01 = new Demo01();
		/**
		 * 通过继承Thread类的类,实例化一个类对象,再通过这个(子)类对象调用Thread类(父)中的start方法,
		 * 本质是一个回调函数,由 start方法新创建的线程会调用这个方法从而执行需要的代码
		 */
		demo01.start();
		//main方法线程体
		for(int i=500;i>0;i--)
		{
			System.out.println("线程2----"+i);
		}
	}
}

二:实现Runnable接口

         1:通过继承Runnable接口类实现对象,
         2:因为Thread类中实例化对象的语句需要传入一个Runnable类型的参数,便把实现了Runnable接口的类对象作为参数传入
         3:再通过Thread类的实例化对象 thread,调用start方法

package thread;

//实现Runnable接口

public class Demo03 implements Runnable
{

	public static void main(String[] args) 
	{
		//创建Runnnable接口的类实现对象
		Demo03 demo03 = new Demo03();
		//创建线程对象,通过线程对象开启线程,称之为代理
		Thread thread = new Thread(demo03);
		/**
		 * 通过继承Runnable接口类实现对象,
		 * 因为Thread类中实例化对象的语句需要传入一个Runnable类型的参数,便把实现了Runnable接口的类对象作为参数传入
		 * 再通过Thread类的实例化对象 thread,调用start方法
		 * 
		 * 上下两个语句还可合并为 new Thread(demo03).start();
		 * 
		 * 两种开启多线程的方法相似的原因是因为Thread类是实现了Runnable接口的类,所以本质上没有区别,
		 * 只是因为在Java中,接口多继承而类只能单继承的特点,更推荐使用实现Runnable接口的方法开启多线程
		 * 
		 * */
		new Thread(demo03).start();
		thread.start();
		//main方法线程体
		for(int i=500;i>0;i--)
		{
			System.out.println("线程2----"+i);
		}
	}

	@Override
	public void run() 
	{
		for(int i= 0;i<20;i++)
		{
			System.out.println("线程1----"+i);
		}
	}

}

ps:两种开启多线程的方法相似的原因是因为Thread类是实现了Runnable接口的类,所以本质上没有区别,只是因为在Java中,接口多继承而类只能单继承的特点,更推荐使用实现Runnable接口的方法开启多线程

三:实现Callable接口

实现Callable接口,创建执行服务,开辟线程空间,执行后关闭线程空间

package thread;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.io.FileUtils;

/*
 * //Callable就是产生线程池的接口
	//可以定义返回值
	//可以抛出异常
	 * 了解即可
 * 
 * */


public class Demo05 implements Callable<Boolean>
{
	
	private String url;
	private String name;
	public Demo05(String url,String name)
	{
		this.name=name;
		this.url=url;
	}

	public static void main(String[] args) throws InterruptedException, ExecutionException 
	{
		Demo05 t1 = new Demo05("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=KameRider&step_word=&hs=0&pn=5&spn=0&di=7060663421280190465&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=2&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=-1&cs=475209920%2C974142725&os=1851668971%2C4069697802&simid=475209920%2C974142725&adpicid=0&lpn=0&ln=275&fr=&fmq=1649684591285_R&fm=result&ic=&s=undefined&hd=&latest=&copyright=&se=&sme=&tab=0&width=&height=&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=https%3A%2F%2Fgimg2.baidu.com%2Fimage_search%2Fsrc%3Dhttp%3A%2F%2Fhbimg.b0.upaiyun.com%2F107790b1f8aaafd68156c85b410f20b6954f7cf64678e-HCGZy5_fw236%26refer%3Dhttp%3A%2F%2Fhbimg.b0.upaiyun.com%26app%3D2002%26size%3Df9999%2C10000%26q%3Da80%26n%3D0%26g%3D0n%26fmt%3Dauto%3Fsec%3D1652276600%26t%3Dcc3df812cee7fc6d65243255a4b98919&fromurl=ippr_z2C%24qAzdH3FAzdH3Fi7wkwg_z%26e3Bv54AzdH3Fk5w61fAzdH3F90bmlcc9AzdH3F&gsm=6&rpstart=0&rpnum=0&islist=&querylist=&nojc=undefined&dyTabStr=MCw0LDUsMSw2LDMsNyw4LDIsOQ%3D%3D","Kuuga");
		Demo05 t2 = new Demo05("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=KameRider&step_word=&hs=0&pn=6&spn=0&di=7060663421280190465&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=2&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=-1&cs=2838076070%2C369928604&os=1639080999%2C1502824316&simid=2838076070%2C369928604&adpicid=0&lpn=0&ln=275&fr=&fmq=1649684591285_R&fm=result&ic=&s=undefined&hd=&latest=&copyright=&se=&sme=&tab=0&width=&height=&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=https%3A%2F%2Fgimg2.baidu.com%2Fimage_search%2Fsrc%3Dhttp%3A%2F%2Fhbimg.b0.upaiyun.com%2F9361d0141ebf125ea6b83a77f9baa917aa61c59454d2b-qgT3Lw_fw236%26refer%3Dhttp%3A%2F%2Fhbimg.b0.upaiyun.com%26app%3D2002%26size%3Df9999%2C10000%26q%3Da80%26n%3D0%26g%3D0n%26fmt%3Dauto%3Fsec%3D1652276600%26t%3Dc5568c850e52143d4d95725455631aef&fromurl=ippr_z2C%24qAzdH3FAzdH3Fi7wkwg_z%26e3Bv54AzdH3Fk5w61fAzdH3F90bmlcc9AzdH3F&gsm=6&rpstart=0&rpnum=0&islist=&querylist=&nojc=undefined&dyTabStr=MCw0LDUsMSw2LDMsNyw4LDIsOQ%3D%3D","Blade");
		Demo05 t3 = new Demo05("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=KameRider&step_word=&hs=0&pn=7&spn=0&di=7060663421280190465&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=2&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=-1&cs=2865016088%2C351628382&os=1583059613%2C1136490781&simid=3433901838%2C126903493&adpicid=0&lpn=0&ln=275&fr=&fmq=1649684591285_R&fm=result&ic=&s=undefined&hd=&latest=&copyright=&se=&sme=&tab=0&width=&height=&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=https%3A%2F%2Fgimg2.baidu.com%2Fimage_search%2Fsrc%3Dhttp%3A%2F%2Fhbimg.b0.upaiyun.com%2F6030ee7e1733a6d6a44f5ef88e56d85ff916c4a05bef2-TvCK7W_fw236%26refer%3Dhttp%3A%2F%2Fhbimg.b0.upaiyun.com%26app%3D2002%26size%3Df9999%2C10000%26q%3Da80%26n%3D0%26g%3D0n%26fmt%3Dauto%3Fsec%3D1652276600%26t%3Def967fc1b9798e6a90abf0d45c0a0c31&fromurl=ippr_z2C%24qAzdH3FAzdH3Fi7wkwg_z%26e3Bv54AzdH3Fk5w61fAzdH3F90bmlcc9AzdH3F&gsm=6&rpstart=0&rpnum=0&islist=&querylist=&nojc=undefined&dyTabStr=MCw0LDUsMSw2LDMsNyw4LDIsOQ%3D%3D","Gaim");
		//创建执行服务
		ExecutorService ser = Executors.newFixedThreadPool(3);//三个线程,则需要开辟三个空间
		//提交执行
		Future<Boolean> result1=ser.submit(t1);
		Future<Boolean> result2=ser.submit(t2);
		Future<Boolean> result3=ser.submit(t3);
		//获取结果
		boolean rs1= result1.get();
		boolean rs2= result2.get();
		boolean rs3= result3.get();
		//关闭服务
		ser.shutdownNow();
		System.out.println(rs1);
		System.out.println(rs2);
		System.out.println(rs3);
	}

	@Override
	public Boolean call() throws Exception 
	{
		WebDownLoader wdl =new WebDownLoader();
		wdl.webdownload(url, name);
		System.out.println("下载了名为"+name+"的图片");
		return true;
	}

}

优点:

        可以定义返回值
        可以抛出异常

ps:Callable就是一个产生线程池的接口

总结:

三种方法调用多线程,以实现Runnable接口的方式居多,也更实用,实现Calable接口的方式在现阶段了解即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饭店孤孤单单

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值