个人简介
- 大家好,我是翰慧腾。一名正在努力学JAVA的大一小白,本文章为初学的笔记,希望各位多多指教。💙
- 欢迎点赞+收藏+留言💜
- 别在该厚脸皮的年纪里过度在意自尊,别再该努力的年纪怨天尤人🧡
一、线程通信
概述:线程通信就是线程间相互发送数据。
线程通信的基础:线程通信通常是在多个线程操作同一个共享资源的时候需要进行通信,且要保证线程安全。
提醒: 上述方法应该使用当前同步锁对象进行调用。
/**
* @author hanhan
* date 2022/4/19 17:29
* 努力已经来不及了,你得拼命
*/
public class Phone {
private boolean flag=false;
public void run(){
//负责来电提醒的线程
new Thread(new Runnable() {
@Override
public void run() {
synchronized (Phone.this){
try {
while(true){
synchronized (Phone.this){
if(flag){
//此时应该是接电话
}else{
//代表要来电提醒了
System.out.println("您好,有电话接入,请接听~~~");
flag=true;
Phone.this.notify();
Phone.this.wait();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//接电话线程,正式接通了
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
synchronized (Phone.this) {
if (flag) {
//可以接听电话
System.out.println("电话接听,通话五分钟");
Thread.sleep(5000);
flag = false;//代表等待电话
Phone.this.notify();
Phone.this.wait();
}else{
Phone.this.notify();
Phone.this.wait();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public static void main(String[] args) {
//创建手机对象
Phone huawei = new Phone();
huawei.run();
}
}
二、线程池(重点)
概述:线程池就是一个可以复用线程的技术,如果没有线程池,用户每次发起一个请求后台就创建一个新线程,而新线程的创建是开销很大的,这样会严重影响系统的性能。
线程池代表:ExecutorService接口
得到线程池对象:
方式一:
面试题:临时线程什么时候创建?
- 新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时会创建临时线程。
什么时候开始拒绝任务?
- 核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始任务拒绝。
import java.util.concurrent.*;
/**
* @author hanhan
* date 2022/4/19 18:35
* 努力已经来不及了,你得拼命
*/
public class ThreadPoorDemo_00 {
public static void main(String[] args) {
ExecutorService e = new ThreadPoolExecutor(3,5,6,
TimeUnit.SECONDS,new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
Runnable my = new MyRunnable_();
//当 e.execute(my)为三个时候,刚好为三个核心线程
e.execute(my);
e.execute(my);
e.execute(my);
//当 e.execute(my)再有五个以上时候就会创建临时线程,因为该队列值为5
e.execute(my);
e.execute(my);
e.execute(my);
e.execute(my);
e.execute(my);
e.execute(my);
e.shutdown();//会等待全部任务执行完毕以后再关闭
// e.shutdownNow();//立即关闭,即使任务没有完成,
}
}class MyRunnable_ implements Runnable{
@Override
public void run() {
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+"输出了"+i);}
try {
System.out.println("本任务与线程绑定了,线程进入");
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.concurrent.*;
/**
* @author hanhan
* date 2022/4/19 22:53
* 努力已经来不及了,你得拼命
*/
public class ThreadPoorDemo_01 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService e = new ThreadPoolExecutor(3,5,6,
TimeUnit.SECONDS,new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
Future<String> s1 = e.submit(new MyCallable_0(10));
Future<String> s2=e.submit(new MyCallable_0(100));
Future<String> s3=e.submit(new MyCallable_0(200));
Future<String> s4=e.submit(new MyCallable_0(300));
System.out.println(s1.get());
System.out.println(s2.get());
System.out.println(s3.get());
System.out.println(s4.get());
}
}
class MyCallable_0 implements Callable<String> {
private int n;
public MyCallable_0(int n){
this.n=n;
}
@Override
public String call() throws Exception {
int sum=0;
for (int i = 0; i < n; i++) {
sum+=i;
}
return Thread.currentThread().getName()+"子线程执行的结果是:"+sum;
}
方式二:Executors的线程池工具类(不推荐使用)