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--多线程的主要内容,如果未能解决你的问题,请参考以下文章