Java要点概述(五)—线程

进程和线程的概念

什么是进程?

进程即一个正在运行的程序,在一个操作系统中,每一个独立运行的程序都可以称为进程。

什么是线程?

线程是进程的执行单元,是用来实现进程功能的必须步骤。每个进程都至少存在一个线程。
当代码按照调用顺序依次往下执行,没有出现程序代码交替运行的效果,这样的程序称为单线程程序。
多段代码交替执行,这样的程序称为多线程程序。
表面上看,多线程程序的线程是并发执行的,但是一个CPU同一时刻只内运行一个线程,只不过CPU运行速度很快,给人一种在同时执行的错觉。
 

线程的创建

线程的三种创建方式

1、继承Thread类,重写run方法

//定义线程类继承Thread类
class MyThread extend Thread {
	//定义一个有参构造
	public MyThread(String name) {
		super(name);
	}
	//重写run方法
	public void run(){
		for(int i=0;i<10;i++){
			System.out.println(Thread.currentThread().getName()+"的run方法执行");
		}
	}
}

2、实现Runnable接口,重写run方法

//定义线程类实现Runnable类
class MyThread implements Runnable {
	//重写run方法
	public void run(){
		for(int i=0;i<10;i++){
			System.out.println(Thread.currentThread().getName()+"的run方法执行");
		}
	}
}

3、实现Callable接口,重写call方法

class MyThread implements Callable<Object> {
	//重写call方法
	public Object call() throws Exception {
		for(int i=0;i<10;i++) {
			System.out.println(Thread.currentThread().getName()+"的run方法执行");
		}
		return "返回值";
	}
}

 

如何去选择线程的创建方式

简单互不影响的线程可以使用继承Thread类,重写run方法实现。当线程存在对唯一数值进行操作时,需要使用实现Runable接口,或者实现Callable接口,重写run方法,因为它只创建一个实现类对象,然后使用Thread类的有参构造去创建线程对象,所以操作的是同一个成员变量。

线程对象的创建

方法一的线程对象的创建运行,直接调用start()方法即可运行。
方法二的线程对象,需要先创建实现类对象,然后使用构造方法Thread(Runnable target,String name)创建。
方法三的线程对象,需要在创建实现类对象的基础上,再使用FutureTask线程结果处理类的有参构造进行封装,FutureTask< Object> ft = new FutureTask<>(mythread),然后再使用Thread类的构造方法创建。
 

线程的生命周期

新建,就绪,阻塞,运行,终止
 

线程操作

线程开启 start()
线程休眠 sleep(long millis) / sleep(long millis, int nanos) 线程转为阻塞状态
线程让步 yield() 线程转为就绪状态
线程插队 join() / join(long millis) 被插队线程阻塞
 

线程同步问题

多线程访问资源的情况下,会出现同一时刻对数据进行操作,可能会出现统计失误,所以我们需要限制某个资源在同一时刻只能被一个线程访问
解决方法:同步代码块 或者 Lock锁

  • 同步代码块:使用synchronized关键字来标识需要限制共享资源的代码片段。
//定义同步代码块,参数为一个锁对象,默认其标志位为1,当其有线程进入时,标志位变为0,线程执行完成后变回1
synchronized(lock){
	//需要进行同步的代码段
}
  • Lock锁
    Lock锁在获取同步锁失败后返回,不再继续等待
//先创建一个锁对象,ReentrantLock为Lock锁接口常用的一个实现类
private final Lock lock = new ReentrantLock();
lock.lock();//调用lock方法上锁
//代码段
lock.unlock();//执行完代码段后解锁

 

线程间的通讯

当多个线程有工序上的要求时,及线程之间需要协同完成工作时,就需要线程之间进行通信。
可以通过Object类的wait()、notify()、notifyAll(),来解决线程通信问题,根据设置条件判断,将线程置于等待或者唤醒线程。
 

线程池

线程池的创建
  • 实现Executor接口
    实现步骤:
    (1) 创建一个实现Runnable接口或Callable接口的实现类,重写run()或者call()方法
    (2) 创建Runnable或Callable实现类对象
    (3) 使用Executors创建线程池
    (4) 使用ExecutorService执行器服务类的submit()方法将Runnable或Callable实现类对象提交到线程池进行管理
    (5) 执行完成后,可以通过shutdown()方法进行关闭。
public static void main(String[] args) throws InterruptedException,ExecutionException{
	//创建线程创建接口实现类对象
	MyThread myThread = new myThread();
	//使用Executors线程执行器类创建可扩展的线程池
	ExecutorService executor = Executor.newCacheThreadPool();
	//Callable的话接收返回结果
	Future<Object> result1 = executor.submit(myThread);
	Future<Object> result1 = executor.submit(myThread);
	//关闭线程池
	executor.shutdown();
	//打印返回结果
	System.out.println("1的返回结果":+result1.get());
	System.out.println("2的返回结果":+result2.get());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

raintempest

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

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

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

打赏作者

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

抵扣说明:

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

余额充值