概念:一个容纳多个线程的容器,其中的线程可以重复使用,省去频繁创建对象,无需反复创建线程而消耗过多资源。
线程池主要是用来解决线程生命周期开销问题和资源不足问题。
使用线程池方式实现Runnable接口:
public class MyRnu implements Runnable{
public void run() { //获取执行当前线程对象的名字 String name=Thread.currentThread().getName(); for(int i=0;i<20;i++){ System.out.println(name+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }}public static void main(String[] args) {
//用线程池的方式完成线程任务 //1.获取线程池对象 ExecutorService es=Executors.newFixedThreadPool(2); //2.创建线程任务对象 MyRnu mr=new MyRnu(); //3.让线程池自主选一条线程执行线程任务 es.submit(mr); //关闭线程池 //es.shutdown(); }使用线程池的方式实现Callable接口:
Cllable接口:用来指定线程的任务。其中的call()方法,用来返回线程任务执行完毕后的结果,call方法可抛出异常。
public class MyCallable implements Callable<String>{
public String call() throws Exception { return "abc"; }}public static void main(String[] args) throws InterruptedException, ExecutionException {
//从线程池工厂中获取线程池对象 ExecutorService es=Executors.newFixedThreadPool(2); //创建线程任务对象 MyCallable mc=new MyCallable(); //让线程池自主选择一条线程执行线程任务 Future<String> f=es.submit(mc); //获取线程任务的返回值 System.out.println(f.get()); }
package com.oracle.demo05;import java.util.concurrent.Callable;public class ZuoyeCall implements Callable{ private int num1; private int num2; public ZuoyeCall() { } public ZuoyeCall(int num1,int num2){ this.num1=num1; this.num2=num2; } public Integer call() throws Exception { //求和 int sum=0; for(int i=num1;i<=num2;i++){ sum+=i; } return sum; }}
package com.oracle.demo05;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class Zuoyedemo { /*用线程池分别计算50..100的和 44..200的和*/ public static void main(String[] args) throws InterruptedException, ExecutionException { //1.从线程池工厂获取线程对象 ExecutorService es=Executors.newFixedThreadPool(2); //2.创建线程任务对象 ZuoyeCall zc1=new ZuoyeCall(50,100); ZuoyeCall zc2=new ZuoyeCall(44,200); //3.从线程池自主选择线程执行任务 Futuref1=es.submit(zc1); Future f2=es.submit(zc2); //4.获取线程任务返回值 int sum1=f1.get(); int sum2=f2.get(); System.out.println(sum1); System.out.println(sum2); //关闭线程 es.shutdown(); }}
线程安全:
线程同步(线程安全处理Synchronized)
方式一:同步代码块
public class Tickets implements Runnable {
// 定义100张电影票 private int tickeet = 100; // 定义同步锁 Object obj = new Object();public void run() {
while (true) { // 同步代码块将可能会产生线程安全问题的代码包括起来 synchronized (obj) {if (tickeet > 0) {
try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "出售第" + tickeet-- + "张票"); } } } }}方式二:同步方法
public class Tickets2 implements Runnable {
// 定义100张电影票 private int tickeet = 100; // 定义同步锁 Object obj = new Object(); public void run() { while (true) { method(); } }//定义同步方法
public synchronized void method(){ if (tickeet > 0) { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "出售第" + tickeet-- + "张票"); } }}同步方法中的锁对象是 this
静态同步方法中的锁对象是 类名.class
Lock接口:
public class Tickets3 implements Runnable {
// 定义100张电影票 private int tickeet = 100; // 创建锁接口对象 Lock lock = new ReentrantLock(); public void run() { while (true) { // 获取锁 lock.lock(); if (tickeet > 0) { try { Thread.sleep(50); System.out.println(Thread.currentThread().getName() + "出售第" + tickeet-- + "张票"); } catch (InterruptedException e) { e.printStackTrace(); } finally { // 释放锁 lock.unlock(); } } } }}