线程池与Lambda表达式

一个线程执行任务的完整流程是:

  1. 创建线程
  2. 创建任务
  3. 执行任务
  4. 关闭线程

这个流程中创建线程和关闭线程耗费的时间在90%,而我们有时候创建线程就是为了执行一个很小的任务,这就会导致效率很低。

而线程池就是一个容纳多个线程的容器,池中的线程可以反复的使用,省去了频繁创建和销毁线程的时间。

线程池分为定长和非定常线程池,线程池的结构可以看作是数组形式,每个下标放一个线程。

四种线程池

Java中有四种线程池:

  • 缓存线程池:
  • 定长线程池:
  • 单线程线程池:
  • 周期性任务定长线程池:

对获取以上四种线程池的对象,用的都是:ExecutorService 对象名 = Executors.newCachedThreadPool( ) ;

缓存线程池:

缓存线程池 (长度无限制)
执行流程:

  1. 判断线程池是否存在空闲线程
  2. 存在则使用
  3. 不存在,则创建线程 并放入线程池, 然后使用

ExecutorService service = Executors.newCachedThreadPool();
//向线程池中 加入 新的任务
service.execute(new Runnable() {
    
    
    @Override
    public void run() {
    
    
    	System.out.println("线程的名称:"+Thread.currentThread().getName());
    }
});
service.execute(new Runnable() {
    
    
    @Override
    public void run() {
    
    
   		System.out.println("线程的名称:"+Thread.currentThread().getName());
    }
});
service.execute(new Runnable() {
    
    
    @Override
    public void run() {
    
    
		System.out.println("线程的名称:"+Thread.currentThread().getName());
}
});

举例:

public class demo7 {
    
    
    public static void main(String[] args) {
    
    
        //创建线程池对象
        ExecutorService service = Executors.newCachedThreadPool();
        //往线程池里面放入新的任务
        service.execute(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(Thread.currentThread().getName()+"窗前明月光");
            }
        });

        service.execute(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(Thread.currentThread().getName()+"窗前明月光");
            }
        });

        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }

        service.execute(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(Thread.currentThread().getName()+"窗前明月光");
            }
        });
    }
}

打印结果:

pool-1-thread-2窗前明月光
pool-1-thread-1窗前明月光
pool-1-thread-2窗前明月光

解释:

往线程池放入两个任务,暂停一秒后再放入第三个任务,可以看到任务一和任务三的线程名称一样。

定长线程池

定长线程池(长度是指定的数值)

执行流程:

  1. 判断线程池是否存在空闲线程
  2. 存在则使用
  3. 不存在空闲线程,且线程池未满的情况下,则创建线程并放入线程池, 然后使用
  4. 不存在空闲线程,且线程池已满的情况下,则等待线程池存在空闲线程
ExecutorService service = Executors.newFixedThreadPool(2);  //在这里确定线程池的长度
service.execute(new Runnable() {
    
    
    @Override
	public void run() {
    
    
		System.out.println("线程的名称:"+Thread.currentThread().getName());
	}
});
service.execute(new Runnable() {
    
    
	@Override
	public void run() {
    
    
		System.out.println("线程的名称:"+Thread.currentThread().getName());
	}
});

3. 单线程线程池

效果与定长线程池创建时传入数值1效果一致

执行流程:

  1. 判断线程池的那个线程是否空闲
  2. 空闲则使用
  3. 不空闲,则等待 池中的单个线程空闲后使用
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new Runnable() {
    
    
	@Override
	public void run() {
    
    
		System.out.println("线程的名称:"+Thread.currentThread().getName());
	}
});
service.execute(new Runnable() {
    
    
	@Override
	public void run() {
    
    
		System.out.println("线程的名称:"+Thread.currentThread().getName());
	}
});

4. 周期性任务定长线程池

周期任务定长线程池执行流程:

  1. 判断线程池是否存在空闲线程

  2. 存在则使用

  3. 不存在空闲线程,且线程池未满的情况下,则创建线程并放入线程池, 然后使用

  4. 不存在空闲线程,且线程池已满的情况下,则等待线程池存在空闲线程

周期性定长线程池是一个定长线程池,可以使任务定时在某个时间执行,也可以使任务定期并周期执行。

举例:

public class demo7_2 {
    
    
    /**
     * 周期性任务定长线程池
     */
    public static void main(String[] args) {
    
    
        ScheduledExecutorService service = Executors.newScheduledThreadPool(2);

        //1.定时执行一次
        /**
         * 参数1. 定时执行的任务
         * 参数2. 时长数字
         * 参数3. 时长数字的时间单位。TimeUnit的常量指定
         */
        service.schedule(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("床前明月光");
            }
        },5, TimeUnit.SECONDS);  //5,单位:秒
        
        //周期执行任务
        /**
         * 参数1. 任务
         * 参数2, 延时时长数字(第一次执行在什么时候以后)
         * 参数3, 周期时长数字(每隔多久执行一次)
         * 参数4, 时长数字单位
         */
        service.scheduleAtFixedRate(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("床前明月光");
            }
        },5,1,TimeUnit.SECONDS);  //5秒后第一次执行,后每隔1秒执行一次
    }
}

Lambda表达式

Lambda表达式是函数式编程思想,意思是写一个方法(函数)直接解决问题,而不像面向对象一样创建对象调用方法来解决问题。

举例:

public static void main(String[] args) {
    
    
        //冗余Runnable代码
        Thread t= new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("床前明月光");
            }
        });
        t.start();
        
        //函数式编程
        Thread t1 = new Thread(() -> System.out.println("床前明月光"));
        t1.start();
    }
public static void main(String[] args) {
    //冗余Runnable代码
    Thread t= new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("床前明月光");
        }
    });
    t.start();
    
    //函数式编程
    Thread t1 = new Thread(() -> System.out.println("床前明月光"));
    t1.start();
}
image-20211123220741726

おすすめ

転載: blog.csdn.net/m0_58702068/article/details/121504647