Java基础:一文讲清多线程和线程池和线程同步
01-概述
02-线程创建
继承Thread
实现Runnable(任务对象)
实现Callable接口
public class ThreadDemo3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 目标:线程创建3
// 需求:求1-100的和
Callable<String> call = new MyCallable(100);
// 创建FutureTask对象
// 是Runnable对象
FutureTask<String> task = new FutureTask<>(call);
Thread t = new Thread(task);
t.start();
String result = task.get();
System.out.println("最终执行结果:" + result);
}
}
// 实现Callable接口
class MyCallable implements Callable<String> {
private int n;
public MyCallable(int n){
this.n = n;
}
@Override
public String call() throws Exception {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum+=i;
}
return "子线程求和(1-" + n + ")的结果是:" + sum;
}
}
三种方式比对
03-Thead的常用方法
04-线程安全
什么是线程安全
程序模仿线程安全
public class Test {
public static void main(String[] args) {
// 目标:掌握线程安全问题
// 1. 创建一个账户对象,两个人共享
Account act = new Account("TCBC-001", 100);
// 2.创建两个线程代表小明和小红,同时去取钱
new DrawThread("小明", act).start();
new DrawThread("小红", act).start();;
}
}
class DrawThread extends Thread {
private Account account;
public DrawThread(String name ,Account account) {
super(name);
this.account = account;
}
@Override
public void run() {
// 小明、小红拿同一个账号对象acc取钱
account.withdraw(100);
}
}
public class Account {
private String actId;
private double money;
// 取钱
public void withdraw(double money) {
String name = Thread.currentThread().getName();
if (this.money < money){
System.out.println(name + "取钱,余额不足,取不了");
return;
}
System.out.println(name + "取钱,取了:" + money);// 模拟网络延迟
this.money -= money;
System.out.println(name + "取钱,剩余" + this.money);
}
05-线程同步
认识线程同步
方法一:同步代码块
方法二:同步方法
方法三:Lock
05-线程通信
06-线程池
认识线程池
如何创建线程池
线程池处理Runnable任务
public class ThreadPoolExcutorDemo1 {
public static void main(String[] args) {
// 1. 创建线程池对象
ExecutorService pool = new ThreadPoolExecutor(3,5,1, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
Runnable task = new MyRunnable();
pool.execute(task);// 自动开启线程并处理
pool.execute(task);
pool.execute(task);
pool.execute(task);// 复用线程
// 生产不会关闭线程池
// pool.shutdown();// 关闭
// pool.shutdownNow();// 立即关闭
pool.execute(task);
pool.execute(task);
pool.execute(task);// 线程4
pool.execute(task);// 线程5
pool.execute(task);// 线程6
pool.execute(task);// 拒绝策略
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在执行");
System.out.println(Thread.currentThread().getName()+"进入休眠");
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
线程池处理Callable任务
public class ThreadPoolExcutorDemo3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1. 创建线程池对象
ExecutorService pool = new ThreadPoolExecutor(3,5,1, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
// 创建FutureTask对象
// 是Runnable对象
Future<Integer> f1 = pool.submit(new MyCallable3(0,50));// 自动开启线程并处理
Future<Integer> f2 = pool.submit(new MyCallable3(50,101));
Integer result1 = f1.get();
System.out.println(result1);
Integer result2 = f2.get();
System.out.println("1-100和" + (result1 + result2));
}
}
// 实现Callable接口
class MyCallable3 implements Callable<Integer> {
private int n;
private int m;
public MyCallable3(int n,int m){
this.n = n;
this.m = m;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = n; i < m; i++) {
sum+=i;
}
return sum;
}
}
Executors工具类实现线程池
07-其它:并发、并行
08-其它:生命周期