多线程

    科技2025-05-04  13

    多线程的六大状态,线程实现的四种方式,线程池。

    一、多线程的六种状态 1、新建状态(New):新创建了一个线程对象。 2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。 3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。 4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种: (一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁) (二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。 (三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁) 5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期 二、多线程的四种实现方式 1.继承Thread类实现如下:

    public static void main(String[] args) { demo demo=new demo(); demo.start(); for (int i=0;i<10;i++){ System.out.println("123"+i); } } static class demo extends Thread{ public void run(){ for (int i=0;i<10;i++){ System.out.println("321"+i); } } }

    2.实现Runnable接口实现如下:

    public static void main(String[] args) { demo demo=new demo(); Thread thread=new Thread(demo); thread.start(); for (int i=0;i<10;i++){ System.out.println("dsa"+i); } } static class demo implements Runnable{ public void run(){ for (int i=0;i<10;i++){ System.out.println("asd"+i); } } }

    3、通过Callable和FutureTask创建线程 a:创建Callable接口的实现类 ,并实现Call方法 b:创建Callable实现类的实现,使用FutureTask类包装Callable对象,该FutureTask对象封装了Callable对象的Call方法的返回值 c:使用FutureTask对象作为Thread对象的target创建并启动线程 d:调用FutureTask对象的get()来获取子线程执行结束的返回值

    public class ThreadDemo03 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Callable<Object> oneCallable = new Tickets<Object>(); FutureTask<Object> oneTask = new FutureTask<Object>(oneCallable); Thread t = new Thread(oneTask); System.out.println(Thread.currentThread().getName()); t.start(); } } class Tickets<Object> implements Callable<Object>{ //重写call方法 @Override public Object call() throws Exception { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName()+"-->我是通过实现Callable接口通过FutureTask包装器来实现的线程"); return null; } }

    4、通过线程池创建线程

    public class ThreadDemo05{ private static int POOL_NUM = 10; //线程池数量 /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub ExecutorService executorService = Executors.newFixedThreadPool(5); for(int i = 0; i<POOL_NUM; i++) { RunnableThread thread = new RunnableThread(); //Thread.sleep(1000); executorService.execute(thread); } //关闭线程池 executorService.shutdown(); } } class RunnableThread implements Runnable { @Override public void run() { System.out.println("通过线程池方式创建的线程:" + Thread.currentThread().getName() + " "); } }

    三、线程池的好处和种类: 线程池:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁的创建线程会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间,线程池就是一个容纳多个线程的容器,池中的线程可以反复使用,省去了频繁创建线程对象的操作,节省了大量的时间和资源。 线程池的好处: 1.降低资源消耗 2.提高响应速度 3.提高线程的可管理性 线程池的种类: 1.缓存线程池(当线程池中没有空闲线程就会创建新的线程) 2.定长线程池(当线程池中没有空闲线程,且在线程池未满的情况下,创建线程,如果线程池已满,则任务排队等待线程空闲后再执行) 3.单线程线程池(池内就一个线程,如果空闲就使用,如不空间任务排队等待执行) 4.周期性任务定长线程池(定时执行,当某个时机触发时,自动执行某任务) lambda表达式:接口必须只有一个抽象方法才能使用lambda

    Processed: 0.022, SQL: 8