初识线程,看线程实现的三种方法

一、概述

什么是多线程?

多线程是指多条路径同时进行,高效不用等待。

这里的同时是短暂执行不同时间片的任务,只是看似同时。很多多线程是模拟出来的,真正的多线程是指有多个CPU,即多核,如服务器。

如果是模拟出来的多线程,即一个CPU的情况下,在同一个时间点,CPU也只能执行一个代码,因为切换的很快,所有就有同时执行的错觉。

什么是三高?

  • 高可用:数据不会出错
  • 高性能:体验好,延时低
  • 高并发:同时操作

多线程有什么特点?

1、方法间调用:普通方法调用,从哪里来到哪里去,闭合的一条路径。
2、多线程使用:开辟了多条路径。

  • 程序:我们编写的代码
  • 进程(Process):正在执行的程序
  • 线程(Thread):进程中可以开辟多条路,每一条都是一个线程
    每个线程都使用自己的工作内存,并且共同分享主存。

二、创建线程的三种方法

方法一:继承Thread类,重写run方法

1、创建:继承 Thread 类,重写 run() 方法
2、启动:创建子类对象,使用 start() 方法

1、实例:

public class StartThread extends Thread{
	//线程入口点
	public void run(){
		for(int i=0;i<5;i++){
			System.out.println("一边听歌");
		}
	}
	public static void main(String[] args) {
	//启动
		StartThread thread = new StartThread();
		thread.start();     //出现两条路径,不保证立即运行,由CPU调用
//		thread.run();       //普通方法调用,没有实现多路径
		for(int i=0;i<10;i++){
			System.out.println("一边coding");
		}
	}
	//多执行几次,每次结果都不一样
}

2、结果:

在这里插入图片描述

3、分析

StartThread thread = new StartThread(); 仅仅是创建了线程对象,需要调用 start() 开启线程,执行 run() 方法。总结如下:

  • 执行线程必须调用start() 加入到调度器中
  • 不一定立即执行,体统安排调度分配执行
  • 直接调用 run() 不是开启多线程,只是普通方法的调用

虽然子类Thread具备了多线程的能力:
启动线程:子类对象.start()
不建议使用:因为OOP具有单继承局限性

方法二:实现Runable接口,重写run方法

1、创建:实现Runnable,重写run() 方法
2、启动:创建实现类的对象+Thread对象+start() 方法

1、实例:

public class StartRun implements Runnable{
	//线程入口点
	public void run(){
		for(int i=0;i<10;i++){
			System.out.println("一边听歌");
		}
	}
	public static void main(String[] args) {
	//创建实现类的对象
		StartRun sr = new StartRun();
	//创建代理类的对象
		Thread t = new Thread(sr);
	//启动
		t.start();     
	}
}

2、分析

  • 实现接口 Runnable 具有多线程能力
  • 启动线程:传入目标对象+Thread对象.start()
  • 推荐使用:OOP多实现,灵活方便,便于对同一份对象的代理。且方便共享资源。

方法三:实现Callable接口,重写call方法

1、实例:

实现图片下载功能

public class CallDownloader implements Callable<Boolean>{
	private String url; //远程路径
	private String name;  //存储名字
	public CallDownloader(String url,String name){
		this.url=url;
		this.name=name;
		System.out.println(name);
	}
	public static void main(String[] args) {
		//1、创建目标对象: 
		CallDownloader cd1 =new CallDownloader("图片地址""baidu. png");
		CallDownloader cd2 =new CallDownloader("图片地址""baidu. png");
		CallDownloader cd3 =new CallDownloader("图片地址""baidu. png");
		//2、创建执行服务: 
		ExecutorService ser = Executors.newFixedThreadPool(3);
		//3、提交执行:  
		Future<Boolean> result1 = ser.submit(cd1);
		Future<Boolean> result2 = ser.submit(cd2);
		Future<Boolean> result3 = ser.submit(cd3);
		//4、获取结果:  
		boolean r1 =result1.get();
		boolean r2 =result2.get();
		boolean r3 =result3.get();
		System.out.println(r1+"--"+r2+"--"+r3);
		//5、关闭服务:
		ser. shutdownNow();
	}
	@Override
	public Boolean call() throws Exception {
		WebDownloader wd = new WebDownloader();
		wd.download(url.name);
		System.out.println(name);
		return true;
	}
}

2、分析:

  • 可以throws出去异常,并且可以返回
  • JUC并发包下,实现Callable接口
步骤:

<1>、创建目标对象
<2>、创建执行服务
<3>、提交执行
<4>、获取结果
<5>、关闭服务

三、总结

少用继承,多用实现(接口),因为单继承有局限性,继承一个类又需要继承许多其他类,需要重构代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值