(1)线程:
线程(Thread)是一份独立运行的程序,有自己专用的运行栈。线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。
(2)线程同步:当多个线程同时读写同一份共享资源的时候,可能会引起冲突。线程同步需要牢记以下4点:
a. 线程同步就是线程排队。同步就是排队。线程同步的目的就是避免线程“同步”执行。这可真是个无聊的绕口令。
b. 只有共享资源的读写访问才需要同步。如果不是共享资源,那么就根本没有同步的必要。
c. 只有“变量”才需要同步访问。如果共享的资源是固定不变的,那么就相当于“常量”,线程同时读取常量也不需要同步。至少一个线程修改共享资源,这样的情况下,线程之间就需要同步。
d. 多个线程访问共享资源的代码有可能是同一份代码,也有可能是不同的代码;无论是否执行同一份代码,只要这些线程的代码访问同一份可变的共享资源,这些线程之间就需要同步。
(3)同步调用:同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果
(4)异步调用:当发送了调用的指令,调用者无需等待被调用的方法完全执行完毕;而是继续执行下面的流程。
例如:在某个调用中,需要顺序调用 A, B, C三个过程方法;如他们都是同步调用,则需要将他们都顺序执行完毕之后,方算作过程执行完毕; 如B为一个异步的调用方法,则在执行完A之后,调用B,并不等待B完成,而是执行开始调用C,待C执行完毕之后,就意味着这个过程执行完毕了。
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();
}
}
@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注解的方法要放在能被扫到的范围内