线程池方式
线程池的概念
- 线程池概念:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗多资源。
线程池的工作原理:
线程池的好处
- 降低资源消耗。减少了创建和销毁线程的次数,每个⼯作线程都可以被重复利⽤,可执⾏多个任务。
- 提⾼响应速度。当任务到达时,任务可以不需要的等到线程创建就能⽴即执⾏。
- 提⾼线程的可管理性。可以根据系统的承受能⼒,调整线程池中⼯作线线程的数⽬,防⽌因为消耗过多的内存,⽽把服务器累趴下( 每个线程需要⼤约 1MB 内存,线程开的越多,消耗的内存也就越⼤,最后死机)
Java⾥⾯线程池的顶级接⼝是java.util.concurrent.Executor,但是严格意义上讲Executor并不是⼀个线程池,⽽只是⼀个执⾏线程的⼯具。真正的线程池接⼝java.util.concurrent.ExecutorService。线程池的使用
- public static ExecutorService newFixedThreadPool(int nThreads):返回线程池对象。( 创建的是有界线程池 , 也就是池中的线程个数可以指定最⼤数量)
获取到了⼀个线程池ExecutorService 对象,那么怎么使⽤呢,在这⾥定义了⼀个使用线程池对象的⽅法如下:
public Future> submit(Runnable task) : 获取线程 池中的某⼀个线程对象,并执⾏任务 publicFuture submit(Callable task) : 获取线程池中的某⼀个线程对象,并执⾏任务
代码:
public class MyRunnable implements Runnable {
@Override
public void run() {
//任务
System.out.println(Thread.currentThread().getName()+":开始执⾏实现Runnable⽅式的任务....");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":执⾏完毕....");
}
}
//线程池测试类
public class Test1_Runnable {
public static void main(String[] args) {
// 1.创建线程池,初始化线程
ExecutorService es =Executors.newFixedThreadPool(3);// 创建⼀个线程池对象,该线程池中有3条线程
// 2.创建任务
MyRunnable mr = new MyRunnable();
// 3.提交并执⾏任务
es.submit(mr);
es.submit(mr);
es.submit(mr);
es.submit(mr);
// 4.销毁线程池(⼀般不操作)
//es.shutdown();
}
}
死锁
- 什么是死锁:在多线程程序中,使⽤了多把锁,造成线程之间相互等待.程序不往下⾛了。
- 产生死锁的条件:1.有多把锁 2.有多个线程 3.有同步代码块嵌套
代码:
public class Test {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
// 任务
synchronized ("锁A") {
System.out.println("张三线程:拿到了锁A, 等待获取锁B...");
synchronized (" 锁B ") {
System.out.println("张三线程: 拿到了锁A,锁B,进⼊了房间");
}
}
}
}).
start();
// 创建并执⾏李四线程
new
Thread(new Runnable() {
@Override
public void run() {
// 任务
synchronized ("锁B") {
System.out.println("李四线程:拿到了锁B,等待获取锁A...");
synchronized ("锁A") {
System.out.println("李四线程: 拿到了锁A,锁B,进⼊了房间");
}
}
}
}).
start();
}
}



