SpringBoot学习笔记(六)-线程同步及异步执行

  1. 概念

(1)线程:
线程(Thread)是一份独立运行的程序,有自己专用的运行栈。线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。

(2)线程同步:当多个线程同时读写同一份共享资源的时候,可能会引起冲突。线程同步需要牢记以下4点:
a. 线程同步就是线程排队。同步就是排队。线程同步的目的就是避免线程“同步”执行。这可真是个无聊的绕口令。
b. 只有共享资源的读写访问才需要同步。如果不是共享资源,那么就根本没有同步的必要。
c. 只有“变量”才需要同步访问。如果共享的资源是固定不变的,那么就相当于“常量”,线程同时读取常量也不需要同步。至少一个线程修改共享资源,这样的情况下,线程之间就需要同步。
d. 多个线程访问共享资源的代码有可能是同一份代码,也有可能是不同的代码;无论是否执行同一份代码,只要这些线程的代码访问同一份可变的共享资源,这些线程之间就需要同步。

(3)同步调用:同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果

(4)异步调用:当发送了调用的指令,调用者无需等待被调用的方法完全执行完毕;而是继续执行下面的流程。

例如:在某个调用中,需要顺序调用 A, B, C三个过程方法;如他们都是同步调用,则需要将他们都顺序执行完毕之后,方算作过程执行完毕; 如B为一个异步的调用方法,则在执行完A之后,调用B,并不等待B完成,而是执行开始调用C,待C执行完毕之后,就意味着这个过程执行完毕了。

  1. 线程创建
    三种方式创建线程:
    参考地址:https://blog.csdn.net/lihua5419/article/details/80679319
    (1)继承Thread方法,重写Thread的run()方法
public class MyThread extends Thread{
 
	 @Override
	public void run() {
		// TODO Auto-generated method stub
		//super.run();
		System.out.println("我是一个线程中的方法");
	}
}

开启线程>>>>

public static void main(String[] args) {
		MyThread myThread=new MyThread();
		myThread.start();//开启一个线程方法
		doSomething();
	 //线程下的方法可与上边的线程并发执行,即使线程未执行完毕
	}

注:创建线程的目的就是要让线程能独立执行,多线程并发执行,不访问共享资源时互不干扰。

(2)实现Runnable接口
一个是继承Thread类,一个是继承Runable接口,具体写法上一致:

public class RunnableThread implements Runnable{
 
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("我是一个线程方法");
	} 
}

不同的是开启线程的方式 ,有一点不一样:

public static void main(String[] args) {
		Runnable runnable=new RunnableThread();
		Thread thread=new Thread(runnable);
		thread.start();//开启一个线程方法
	        //以下的方法可与上边的线程并发执行
		doSomething();
	}

(3)实现Callable接口和Future创建线程
首先创建Callable接口的实现类CallableThread,实现call()方法,并且有返回值。Callable接口是一个带泛型的接口,泛型的类型就是线程返回值的类型。实现Callable接口中的call()方法,方法的返回类型与泛型的类型相同:

public class CallableThread implements Callable<String>{
 
	@Override
	public String call() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("我是线程中的方法");
		return "需要返回的值";
	}
}

Callable不能直接获取返回值,需要用FutureTask在外部封装一下再获取返回值:

public static void main(String[] args) {
		Callable<String> callable=new CallableThread();
		FutureTask<String> futureTask=new FutureTask<String>(callable);
		Thread thread=new Thread(futureTask);
		thread.start();//开启一个线程方法
	        //以下的方法可与上边的线程并发执行
		doSomething();
		try {
			futureTask.get();//获取线程返回值
		} catch (InterruptedException | ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
  1. 同步锁 synchronized
    参考地址:https://blog.csdn.net/yx0628/article/details/79086511
    同步锁的分类大概有两种:
    (1)对象锁
    当synchronized用来修饰“非静态方法”或修饰“代码块(参数是this)”时,这时synchronized是对象锁
    (2)类锁
    当synchronized用来修饰“静态方法”或修饰“代码块(参数是xxx.class)”时,这时synchronized是类锁
    结论:
    a. 当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块,同步方法也是。
    b. 当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。同步方法也是。
    也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
    c. 当类锁和对象锁同时存在时,两种锁互不干扰
  2. 注解创建线程
    参考地址:https://www.cnblogs.com/wihainan/p/6516858.html
    (1)@Async:
    在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,即指将被注解的方法放到一个新创建线程,调用者无需等待它的完成,即可继续其他的操作。
    使用方式:
    在SpringBoot启动类上或Spring框架的Controller类加上@EnableAsync
@EnableAsync
@SpringBootApplication
public class SpringbootApplication {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SpringApplication.run(SpringbootApplication.class, args);
	}
}

基于@Async无返回值调用

@Async  //标注使用  
2 public void asyncMethodWithVoidReturnType() {  
3     System.out.println("Execute method asynchronously. "  
4       + Thread.currentThread().getName());  
5 }  

基于@Async返回值的调用

@Async  
 2 public Future<String> asyncMethodWithReturnType() {  
 3     System.out.println("Execute method asynchronously - "  + Thread.currentThread().getName());  
 4     try {  
 5         Thread.sleep(5000);  
 6         return new AsyncResult<String>("hello world !!!!");  
 7     } catch (InterruptedException e) {  
 8         //  
 9     }  
10    
11     return null;  
12 } 

注:@Async注解的方法要放在能被扫到的范围内

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以和你分享一些关于Spring Boot的学习笔记。 1. Spring Boot是什么? Spring Boot是一个基于Spring框架的快速开发框架,它能够帮助开发者快速搭建Spring项目,简化了Spring应用开发的繁琐过程,提高了开发效率。 2. Spring Boot的优点有哪些? Spring Boot的优点有很多,其中包括: - 简化了Spring应用的开发,提高了开发效率; - 集成了很多常用的第三方库,减少了依赖管理的工作; - 自动化配置,减少了配置文件的编写工作; - 内嵌了Tomcat等Web容器,使得应用的部署更加便捷; - 提供了Actuator等模块,使得应用的监控和管理更加便捷。 3. Spring Boot的核心注解有哪些? Spring Boot的核心注解包括: - @SpringBootApplication:标注在启动类上,代表这是一个Spring Boot应用; - @Controller:标注在控制器类上,处理HTTP请求; - @Service:标注在服务类上,用于处理业务逻辑; - @Repository:标注在数据访问类上,用于数据库访问; - @Configuration:标注在配置类上,用于配置Spring应用上下文。 4. Spring Boot的配置文件有哪些? Spring Boot的配置文件包括: - application.properties:基于Key-Value的属性文件; - application.yml:基于YAML语法的配置文件。 5. 如何使用Spring Boot集成数据库? 使用Spring Boot集成数据库需要完成以下几个步骤: - 在pom.xml中添加相关数据库依赖; - 配置数据源和JPA/Hibernate等相关配置; - 编写实体类和DAO层代码。 以上就是一些关于Spring Boot的学习笔记,希望能对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值