文章目录
创建线程
1.继承thread
执行流程:
客户端调用start()方法----private native void start0();---控制权交给jvm ----抢到资源后,执行该线程父类自定义过的自己又去重写的run()方法
实例代码:
public class Demo1 extends Thread {
public Demo1(String name) {
super(name);
}
@Override
public void run() {
while(!interrupted()){
System.out.println(getName()+ " 线程执行了....");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
Demo1 demo1 = new Demo1("线程1");
demo1.start();
}
}
运行结果:
2.实现runnable接口:
执行流程:
作为线程任务存在:线程所要做的功能 相当于给线程和任务分类,让代码更解耦 thread---new thread(target) --init方法将全局的target赋值传递过来当前线程任务---jvm 调用 ---target.run方法
英文翻译:
- 1.如果此线程是使用单独的
Runnable
运行对象构造的,则将调用Runnable
对象的run
方法; *否则,此方法不执行任何操作并返回。 - 2.·Thread `的子类应重写此方法.
这里就是第1种情况,调用我们传递的runable对象的run方法。
实例代码:
public class Demo2 implements Runnable{
@Override
public void run() {
while(true){
System.out.println("thread running ...");
}
}
public static void main(String[] args) {
Thread thread = new Thread(new Demo2());
thread.start();
}
}
运行结果:
3.匿名内部类的方式:
本质:只有一个线程的情况,实例不用给名字了,直接new完再用,其实也是结果上面两种方式的执行。
①重写thead类+匿名内部类
public static void main(String[] args) {
//如果只有一个线程的话,可以使用匿名内部类
//使用匿名内部类,相当于线程子类
new Thread(){
@Override
public void run() {
System.out.println("thread start1....");
}
}.start();
}
②实现runnable+匿名内部类
//把线程任务作为参数传递
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("thread start2....");
}
}).start();
③实现runnable+重写thead类+匿名内部类
可以这么写,但是平时不怎么干。
//把线程任务作为参数传递
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("thread start2....");
}
}){
@Override
public void run() {
System.out.println("thread start1....");
}
}.start();
运行结果: thread start1…
为啥尼?
这里涉及到了jvm中的方法调用动态分派的知识:也就是方法重写的原理。
实现了runable接口,作为线程任务参数传递进去,但是jvm会在执行时调用子类的run,和自己这个类的run方法没关系了,即使有target也不会被执行。
子类thread重写了run方法,根据jvm方法重写的原理,方法调用动态分派会调用子类的run方法
4.创建既有返回值和异常的线程
原理是啥先不用管,后面在补充吧,代码演示如下:
public class Demo4 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("正在进行进行紧张的计算");
Thread.sleep(3000);
return 1;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//作为执行的任务
Demo4 demo4 = new Demo4();
//封装
FutureTask<Integer> task = new FutureTask<>(demo4);
//包装到thread类
Thread thread = new Thread(task);
thread.start();
System.out.println("我先干点别的");
//拿到结果
Integer result = task.get();
System.out.println(result);
}
}
运行结果:
运行了线程,还返回了值,牛。
5.定时器
timer
看下他的api:
代码演示:
public class Demo5 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("timetask is run");
}
},0,1000);
}
}
运行结果:
缺点:
当一个Timer 运行多个TimerTask 时,只要其中一个TimerTask 在执行中向run 方法
外抛出了异常,则其他任务也会自动终止。
5.线程池
public class Demo6 {
public static void main(String[] args) {
//10个线程的线程池
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for (int i=0;i<100;i++){
//创建线程任务
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}
//停掉线程池
threadPool.shutdown();
}
}
运行结果:
演示2:
public class Demo6 {
public static void main(String[] args) {
//自动创建线程池的大小,不够用就创建,用完就回收。
ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i=0;i<100;i++){
//创建线程任务
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}
//停掉线程池
threadPool.shutdown();
}
}
6. spring的多线程方式
pom
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
Config
@Configurable
@ComponentScan("com.hfl.demo.liquidbasedemo.quartz")
@EnableAsync
public class Config implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {//实现AsyncConfigurer接口并重写getAsyncExecutor方法,并返回一个ThreadPoolTaskExecutor,这样我们就获得了一个基于线程池TaskExecutor
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(10);
taskExecutor.setMaxPoolSize(80);
taskExecutor.setQueueCapacity(100);
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
DemoService
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class DemoService {
@Async
public void a(){
while(true){
System.out.println("执行a方法");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Async
public void b(){
while(true){
System.out.println("执行b方法");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试Test
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
DemoService ds = ac.getBean(DemoService.class);
ds.a();
ds.b();
}
}
运行结果:循环执行
7.使用lambd表达式
将有顺序的流分成几块,然后并行,分别执行结果。关键词是parallelStream
:
演示:
/**
* 代码简洁
* 并发支持
*/
public class Demo7 {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(19,34, 56, 34);
numbers.parallelStream().forEach(System.out::println);
}
}
运行结果:
完