java死锁、线程状态、线程通信、线程池
1. 回顾
java实现多线程: [1]继承Thread类并重写run方法 [2]实现Runnable接口
线程Thread中常用的方法: setName(): Thread.currentThread().getName():
static void sleep(); static void yield(): join(): setDeamon()设置后台线程
- 线程安全问题: ---当多个线程共享同一个资源时,对该资源的操作就会出现线程安全问题。
- 手动锁 Lock它是一个接口--lock() unlock() <finally中>
- 自动锁synchronized
2. 正文
- 什么是死锁
- 线程都有哪些状态?
- 线程通信( 了解 wait 和sleep的区别)
- 线程池。
3. 什么是死锁
//死锁小案例
import java.util.concurrent.locks.ReentrantLock;
public class ccc {
public static Object lock = new Object();
public static Object lock2 = new Object();
}
public class eee extends Thread {
@Override
public void run() {
synchronized (ccc.lock){
System.out.println("aaa");
synchronized (ccc.lock2){
System.out.println("bbb");
}
}
}}
public class fff extends Thread{
public void run(){
synchronized (ccc.lock2){
System.out.println("fff");
synchronized (ccc.lock){
System.out.println("e");
}
}
}
}
public class ddd {
public static void main(String[] args) throws InterruptedException {
eee eee = new eee();
fff fff = new fff();
eee.start();
Thread.sleep(100);
fff.start();
}
}
如何解决死锁: (1) 减少同步代码块的嵌套。 (2)设置锁的超时时间。(3)可以使用安全类-jdk提高的安全类。
4. 线程通信
notify():唤醒。
sleep和wait方法的区别?
(1) 来自不同的类: sleep来自于Thread, wait来自Object类。
(2) 是否释放锁资源: sleep不会释放锁资源。wait会释放锁资源。
(3) 用法: sleep时间到了自然会醒,而wait需要调用notify或notifyAll()方法唤醒。
notify和notifyAll()方法的区别?
1.notify随机唤醒等待队列中一个线程,而notifyAll会唤醒等待队列中所有的线程。
5. 线程的状态
NEW:新建状态 RUNNABLE: start()就绪状态-时间片-运行状态. 统称为RUNNABLE BLOCKED: 堵塞状态。加锁时就如该状态 WAITING: 无期等待: 调用wait方法时会进入该状态 TIMED_WAITING: 有期等待---当调用sleep方法时就会进入该状态 TERMINATED: 终止状态。线程的任务代码执行完毕或出现异常。
线程的状态之间可以通过调用相应的方法,进行转换。
6. 线程池
线程池的原理:
线程池的创建
package demo08;
import java.util.concurrent.*;
/*
Executor: 它是线程池的根接口:
void execute(Runnable command):执行Runnable类型的任务。
ExecutorService: 它是Executor的子接口。---
void shutdown():关闭线程池。需要等任务执行完毕。
shutdownNow(); 立即关闭线程池。 不在接受新的任务。
isShutdown(): 判断是否执行了关闭。
isTerminated(): 判断线程池是否终止。表示线程池中的任务都执行完毕,并且线程池关闭了
submit(Callable<T> task);提交任务,可以提交Callable
submit(Runnable task): 提交任务,可以提交Runnable任务
Executors: 它是线程池的工具类,该类提供了创建线程池的一些静态方法
*/
public class Test {
public static void main(String[] args) {
//1.创建一个固定长度的线程池。
// ExecutorService executorService = Executors.newFixedThreadPool(5);
//2. 单一线程池。
// ExecutorService executorService = Executors.newSingleThreadExecutor();
//3. 可变线程池--缓存线程池
// ExecutorService executorService = Executors.newCachedThreadPool();
//4. 延迟线程池。
// ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
// for(int i=0;i<100;i++) {
// executorService.submit(new Runnable() {
// public void run() {
// System.out.println(Thread.currentThread().getName() + "~~~~~~~~~~~~~~~~~~~");
// }
// });
//// executorService.schedule(new Runnable() {
//// public void run() {
//// System.out.println(Thread.currentThread().getName() + "~~~~~~~~~~~~~~~~~~~");
//// }
//// },10, TimeUnit.SECONDS);
// }
// executorService.shutdown();
//上面通过Executors工具类创建线程池,但是阿里巴巴不建议使用。阿里建议使用原生的模式创建线程池。
/*
int corePoolSize,核心线程的个数
int maximumPoolSize,最多的线程个数
long keepAliveTime, 线程空闲时间。
TimeUnit unit, 空闲的单位
BlockingQueue<Runnable> workQueue:等待队列
*/
BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue(5);//最多5等待的任务
ThreadPoolExecutor executor=new ThreadPoolExecutor(5,10,10,TimeUnit.SECONDS,workQueue);
//灵活:
for(int i=0;i<25;i++){
executor.submit(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()+"~~~~~~~~~~~~~~~");
}
});
}
}
}
7. Callable创建线程
package demo09;
import demo03.My;
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// MyCallable myCallable=new MyCallable();
// FutureTask<Integer> task=new FutureTask<Integer>(myCallable);//把线程任务封装到该类中,该类可以获取线程任务执行后的结果.
// Thread t=new Thread(task);
// t.start();
//
// System.out.println(task.get());
//发现线程执行非常麻烦。都使用线程池来执行任务。---不要自己创建线程对象,而是使用线程池中的对象
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Integer> submit =executorService.submit(new MyCallable());
System.out.println(submit.get());
}
}
class MyCallable implements Callable<Integer>{
//线程任务:
public Integer call() throws Exception {
int sum=0;
for(int i=0;i<=10;i++){
sum+=i;
}
return sum;
}
}
class MyRunnable implements Runnable{
public void run() {
}
}
本文来自博客园,作者:知行合二为一,转载请注明原文链接:https://www.cnblogs.com/226zjw/p/17632471.html