多线程 多个线程同时或交替运行, 单核CPU为顺序执行(交替执行), 多核情况下, 每个CPU有自己的运算器, 所以在多个CPU中可以同时运行.
创建线程的方式 1.继承Thread
public class MyThread extends Thread { @Override public void run () { super .run(); System.out.println(Thread.currentThread().getName() + "执行完毕" ); } }
public class ThreadTest { public static void main (String[] args) { MyThread myThread = new MyThread(); myThread.setName("测试" ); myThread.start(); System.out.println(Thread.currentThread().getName() + "执行完毕" ); } }
开始线程, 可以看出main线程和测试线程是两个独立的线程 调用myThread.run();方法相当于直接在主线程运行run方法, 而不是开启一个新的线程去执行
2.实现Runnable接口
public class MyRunable implements Runnable { @Override public void run () { System.out.println(Thread.currentThread().getName() + "执行完毕" ); } }
public class ThreadTest { public static void main (String[] args) { MyRunable runable = new MyRunable(); Thread thread = new Thread(runable); thread.start(); System.out.println(Thread.currentThread().getName() + "执行完毕" ); } }
3.使用线程池 3.1 可以在spring中配置相关线程池, 使用时从容器取出即可, 也可以自己声明线程池
<bean id ="threadPool" class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" > <property name ="corePoolSize" value ="5" /> <property name ="maxPoolSize" value ="20" /> <property name ="keepAliveSeconds" value ="300" /> <property name ="queueCapacity" value ="2000" /> <property name ="rejectedExecutionHandler" > <bean class ="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </property > </bean >
3.2 Executors 创建线程池
public class ThreadTest { public static void main (String[] args) { ExecutorService threadPool = Executors.newCachedThreadPool(); for (int i = 0 ; i < 10 ; i++) { threadPool.execute(new MyRunable()); } } }
当手动创建线程池时, 如果IDEA安装阿里 P3C 插件后会报错提示以下内容, 建议
线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明: Executors 返回的线程池对象的弊端如下: 1) FixedThreadPool 和 SingleThreadPool: 允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。 2) CachedThreadPool 和 ScheduledThreadPool: 允许的创建线程数量为 Integer.MAX_VALUE, 可能会创建大量的线程,从而导致 OOM。
建议使用如下方式:
public class ThreadTest { public static void main (String[] args) { ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(3 , new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d" ).build()); executorService.scheduleAtFixedRate(new MyRunable(), 0 , 1 , TimeUnit.SECONDS); } }
public class ThreadTest { public static void main (String[] args) { ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() .setNameFormat("demo-pool-%d" ).build(); ExecutorService pool = new ThreadPoolExecutor(5 , 20 , 0L , TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024 ), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy()); pool.execute(()-> System.out.println(Thread.currentThread().getName())); pool.shutdown(); } }
线程优先级 1.myThread.setPriority(1);设置优先级 2.优先级从低到高为 1-10, Thread类提供 Thread.MIN_PRIORITY=1, Thread.NORM_PRIORITY=5, Thread.MAX_PRIORITY=10 3.默认优先级为 5 即 NORM_PRIORITY 4.优先级高的仅代表获取进入运行机会的几率大, 并不代表一定会比优先级低的先执行
sleep()和wait() 1.sleep()线程未释放锁, 时间结束后线程继续执行 2.wait线程释放锁, 需要使用notify或notifyAll 3.wait常用于线程之间的交互
package com.liuzhihang.tool.alternate;public class AlternateNum { public static void main (String[] args) { Num num = new Num(); Thread thread1 = new Thread(new Odd(num)); Thread thread2 = new Thread(new Even(num)); thread1.start(); thread2.start(); } } class Num { int anInt = 1 ; boolean flag = true ; } class Odd implements Runnable { private Num num; public Odd (Num num) { this .num = num; } @Override public void run () { while (num.anInt < 1000 ) { synchronized (num) { if (num.flag) { System.out.println("奇数 -> " + num.anInt); num.anInt++; num.flag = false ; num.notify(); } else { try { num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } class Even implements Runnable { private Num num; public Even (Num num) { this .num = num; } @Override public void run () { while (num.anInt < 1000 ) { synchronized (num) { if (!num.flag) { System.out.println("偶数 -> " + num.anInt); num.anInt++; num.flag = true ; num.notify(); } else { try { num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }