创建线程
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); } }
运行结果:
完