days21--多线程

Posted 安小猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了days21--多线程相关的知识,希望对你有一定的参考价值。

进程和线程的区别

进程:
正在执行的程序
是系统进行资源分配和管理的独立单位
每一个进程都有他自己的内存空间和系统资源

线程:
进程中某一个执行流程,可叫做流程控制单元
线程是进程中最小的执行单位
单线程:一个执行路近
多线程:多个执行路近(同时去执行)
注意:
main方法也是一个线程

创建线程的三种方式多线程详解
方式1:通过Thread(实体类)类

步骤:
1.创建类继承Thread
2.重写run
3.创建对象
4.调用start

多线程的实现方式二:实现Runnable接口

步骤:
定义一个类实现Runnable接口
在类中重写run方法
创建类的对象
创建Thread对象,把类的对象作为构造方法的参数
启动线程

实现Runnable的好处

避免了Java的单继承的局限性

适合多个线程去同时处理同一个资源

多线程的实现方式三:实现Callable接口

步骤:
定义一个类重写Callable接口
在类中重写Call方法
创建类的对象
创建FutureTask对象,把类的对象作为构造方法的参数
启动线程

实现Callable的好处

Call()方法有返回值,借助FutureTask类可以获取返回结果
Call()方法可以抛出异常,run()方法不可以

run和start的区别

run:封装线程执行的代码,直接调用,相当于普通方法(单线程)
start:启动线程,由JVM执行run方法

线程的随机性

多线程同时执行,对于开发人员来说,是同时执行 ,对于系统来说,CPU每一时刻只执行一个线程,多个线程同时执行,是CPU在做着快速切换(分时)

线程调度:

分时:所有线程平均分配使用CPU的时间
抢占:所有线程同时去抢CPU,谁抢到谁运行,默认抢到CPU概率(优先级)都是相同的,优先级可以手动调整。优先级高的线程只是提供了一种可能性,抢到CPU的时间相对较多

java线程优先级

int getPriority():获取优先级
void setPriority():设置优先级
注意:
java中默认优先级为5 最小为1 最大为10

线程常用方法

void SetName(String name):将线程的名称设置为name
String getName():返回次线程的名称
Thread(String name):构造函数,线程对象一建立就可以指定名称
static Thread currentThread():获取当前线程对象

控制方法

void sleep(long millis) 使当前正在执行的线程暂停指定的毫秒数
void join() 等待当前线程的死亡
void yield() 线程从运行态切换到就绪态,礼让其他线程
void join(long millis) 等待millis时间的线程死亡,时间结束继续执行
void interrupt() 给线程打上中断标记,并不是真的中断线程
void setDaemon(boolean on) 将此线程标记为守护线程,此线程随着其他线程的 死亡而死亡,会有延迟,当运行的线程都是守护线程时,Java虚拟机将退出
void stop() 停止当前线程

资源共享:

多个线程操作同一资源,容易出现数据安全问题

如何判断出现数据安全问题?

是否是多线程
是否有共享数据
是否有多个语句操作共享数据

解决办法:线程同步(synchronized)

同步代码块:锁的是任意对象
格式:
synchronized(任意对象){
多条语句操作共享数据的代码
}
synchronize(任意对象):给代码加上锁,任意对象就可以看做锁

好处和弊端:
好处:解决了数据安全问题
弊端:线程很多时,每个线程都要执行synchronize,消耗资源,会降低执行效率

同步方法:this
格式:
修饰符 synchronized 返回值类型 方法名(参数){}

同步静态方法:当前类.class
格式:
修饰符 static synchronized 返回值类型 方法名(参数){}

线程通信:

wait():获取到锁的线程进入阻塞状态
notify():随机唤醒被wait()的一个线程
notifyAll():唤醒被wait()的所有线程

java线程池线程池详解

为什么要使用线程池

频繁的线程创建和销毁会占用更多的CPU和内存
频繁的线程创建和销毁会对GC产生比较大的压力
线程太多,线程切换带来的开销将不可忽视
线程太少,多核CPU得不到充分利用,是一种浪费

创建线程池:通过线程工厂类Executors调用一下静态方法

创建单一线程的线程池 Executors.newSingleThreadExecutor();
创建固定数量的线程池 Executors.newFixedThreadPool(int nThreads);
创建带缓存的线程池 Executors.newCachedThreadPool();
创建定时调度的线程池 Executors.newScheduledThreadPool(intcorePoolSize);

创建流式(fork-join)线程池Executors. newWorkStealingPool();

提交任务(启动线程)

execute()用于提交不需要返回结果的任务
submit()用于提交一个需要返回果的任务。该方法返回一个Future对象,通过调用这个对象的get()方法,我们就能获得返回结果

关闭线程池

shutdown()会将线程池状态置为SHUTDOWN,不再接受新的任务,同时会等待线程池中已有的任务执行完成再结束。
shutdownNow()会将线程池状态置为SHUTDOWN,对所有线程执行interrupt()操作,清空队列,并将队列中的任务返回回来。

另外,关闭线程池涉及到两个返回boolean的方法,isShutdown()和isTerminated,分别表示是否关闭和是否终止。

以上是关于days21--多线程的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程Day21-JUC锁之Condition条件

day21&22&23:线程进程协程

毕向东Java视频学习笔记Day11-Day13 多线程

Python开发Day9(多线程多进程)

Day10 多线程理论 开启线程

day35 python多线程