spring boot 多线程数据隔离 springboot多线程读取文件 您所在的位置:网站首页 多线程读取文件数据的方法 spring boot 多线程数据隔离 springboot多线程读取文件

spring boot 多线程数据隔离 springboot多线程读取文件

2024-07-15 12:06| 来源: 网络整理| 查看: 265

概念

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

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

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

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

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

线程创建 三种方式创建线程: 参考地址: (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(); } }同步锁 synchronized 参考地址: 同步锁的分类大概有两种: (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. 当类锁和对象锁同时存在时,两种锁互不干扰注解创建线程 参考地址: (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注解的方法要放在能被扫到的范围内



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有