概念:一个容纳多个线程的容器,其中的线程可以重复使用,省去频繁创建对象,无需反复创建线程而消耗过多资源。
线程池主要是用来解决线程生命周期开销问题和资源不足问题。
使用线程池方式实现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<Integer>{ 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.从线程池自主选择线程执行任务 Future<Integer> f1=es.submit(zc1); Future<Integer> 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();
}
}
}
}
}