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

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

public static void main(String[] args) {
		Callable callable=new CallableThread();
		FutureTask futureTask=new FutureTask(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 asyncMethodWithReturnType() {  
 3     System.out.println("Execute method asynchronously - "  + Thread.currentThread().getName());  
 4     try {  
 5         Thread.sleep(5000);  
 6         return new AsyncResult("hello world !!!!");  
 7     } catch (InterruptedException e) {  
 8         //  
 9     }  
10    
11     return null;  
12 } 

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

你可能感兴趣的:(SpringBoot相关)