1、线程与进程的区别
进程是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间
线程是指进程中的一个执行路径,共享一个进程的内存空间,线程之间可以自由切换,可以并发执行,一个进程至少有一个线程。
线程是在进程的基础上的划分,进程启动后,多个执行路径可以划分为多个进程
2、线程调度(分时调度与抢占式调度)
(线程的最大执行数量是由电脑CPU决定的),所以需要合理的分配资源提高运行效率。
分时调度:所有的线程轮流使用CUP的使用权,平均分配每个线程的时间。
抢占式调度:优先级高的先用,优先级一样谁抢到就是谁的(随机),Java使用的就是抢占式
注意:多线程程序并不能提高运行速度,但是能提高运行效率。
3、同步(线程安全)与异步(线程不安全)
同步:排队执行,效率低但是安全(每个线程排队,不会重复执行)
异步:同时执行,效率高但是数据会不安全(所有线程一起执行一件事情,可会发生重复的执行一段代码)
4、并发与并行
并发:指多个事情在同一个时间段内发生。
并行:多个事情在同一秒/毫秒同时发生的。
5、代码层次什么是多线程
每个线程都拥有自己的栈空间,但是他们都公用了一份堆内存。
6、多线程的实现方式(三种) //run方法 就是线程要执行的任务方法
1、继承(Thread)
创建一个线程对象(1、创建类 。2、直接继承Thread类,然后重写run方法。)
使用start方法执行这个线程
注意该条执行路径的触发方式,不是用对象调用run方法,而是通过thread对象的start()方法来启动任务的。
2、接口(Runnable)
创建Runnable方法,然后实现run方法。)
创建一个线程,并且为他分配一个任务对象(第一步对象)
使用start方法执行这个线程
实现Runnable 与继承 Thread相比的优势:{
1、通过创建任务,然后给线程分配的方式来实现的多线程,更加适合多个线程同时执行相同的任务的情况。
2、可以避免单继承所带来的局限性。
3、任务与线程本身是分离的,提高了程序的健壮性。
4、线程池技术,接受Runnable类型的任务,不接收Thread类型的线程。
}
3、接口(callable)
创建Callable接口,实现call方法
创建FutureTask对象,并传入第一步编写的Callable对象
通过Thread,启动线程
实现Runnable 与 Callable相比的不同点:{
1、Runnable没有返回值;Callable可以返回执行结果
2、Callable接口的call()允许抛出异常;Runnable的run()不行
}
Callable接口支持返回执行结果,需要调用get方法获取,此方法会阻塞主进程的继续执行
isDone() 用于判断是否子线程执行完毕。
cancel()取消子线程,
7、线程概念(一个线程是一个独立的执行路径,是否应该结束,应该由自身决定)
线程阻塞:所有消耗时间的线程操作都可以叫做线程阻塞
线程中断:其中线程发现了中断的标记(抓住了线程中断的异常),结束线程。(注意stop方法已经过时,用return)
线程分为守护线程与用户线程
守护线程:当所有的用户线程结束后,守护线程自动结束。不可控制结束
用户线程:当进程不包含任何的存活的用户进程时候,进行结束
8、常用Thread的一些方法
1、getName() 获取线程名称 ;setName()设置线程名称
2、currentThread() 当前运行的进程
3、sleep(毫秒) 线程休眠,
4、interrupt()添加线程中断标记
5、setDaemon(true)设置守护线程 参数true 代表守护线程
9、线程的六种状态:
NEW 尚未启动的线程为该种状态
RUNNABLE Java虚拟机种执行的线程处于该状态
BLOCKED 被阻塞等待监视器锁定的线程在该状态
WAITING 无线等待另一个线程执行特定操作的线程处于该状态
TIMED WAITING 正在等待另一个线程执行最多指定等待时间的操作的线程处于此状态
TERMINATED 已退出的线程处于此状态。
(锁synchronized)
1、线程不安全的三种处理方式(加锁)
(1)同步代码块。 格式:synchronized(锁对象—可以是任何对象){ }
注意:如果每个线程都用自己的锁对象,则无效果,锁对象应该为所有线程公用的对象
(2)同步方法。创建一个公用方法,定义方法时在定义类型前面加上synchronized
(3)显示锁Lock(自己加锁,自己解锁)。
同步代码块与同步方法都是隐式锁。
创建锁 Lock l = new ReentrantLock();
l.lock()。加锁 l.unlock() 解锁
2、公平锁与不公平锁(只可以显示锁) 、死锁
公平锁:锁解开后,先来先到,
不公平锁:锁解开后,所有一起线程一起抢。
创建对象时候,参数fair为true就是公平锁
Lock l = new ReentrantLock(true);
死锁:A等B解锁,B等A解锁。互相锁住了
线程池
线程池就是一个容纳多个线程的容器,池中的线程可以反复使用,节约创建线程与结束线程的时间。
四种线程池
无论是哪种线程池最后获取的对象都为 ExecutorService
1、缓存线程池(长度无限制)
执行流程: 1)判断线程池是否存在空闲线程
(2)存在直接使用
(3)不存在,则创建线程,并放入线程池,然后使用
创建缓存的线程池
ExecutorService service = Executors.newCachedThreadPool();
加入新的任务(指挥线程池执行新任务): execute对象
service.execute(new Runnable()对象)
2、定长线程池(长度是指定的数值)
执行流程: (1)判断线程池是否存在空闲线程
(2)存在直接使用
(3)不存在,在线程池未满的情况下,则创建线程,并放入线程池,然后使用
(4) 不存在,且线程池已经满了,则等待线程有空闲线程
创建定长的线程池
ExecutorService service = Executors.newFixedThreadPool(长度);
加入新的任务(指挥线程池执行新任务): execute对象
service.execute(new Runnable()对象)
3、单线程线程池
执行流程: (1)判断线程池的那个线程是否空闲
(2)空闲则使用
(3)不空闲,则等待线程池种的单个线程空闲后使用
创建单线程的线程池
ExecutorService service = Executors.newSingleThreadPool(长度);
加入新的任务(指挥线程池执行新任务): execute对象
service.execute(new Runnable()对象)
4、周期定长线程池
执行流程: (1)判断线程池是否存在空闲线程
(2)存在直接使用
(3)不存在,在线程池未满的情况下,则创建线程,并放入线程池,然后使用
(4) 不存在,且线程池已经满了,则等待线程有空闲线程
周期性任务执行时:
定时执行,当某个时机触发时,自动执行某任务
ScheduleExecutorService service = Executors.newScheduledThreadPool(长度);
定时执行一次,
参数1.定时执行的任务,
参数2.时长数字,
参数3.时长数字的时间单位,TimeUnit的常量指定(秒)
service.schedule(new Runnable()对象,时长数字,TimeUnit.seconds)
周期性执行任务(scheduleAtFixedRate方法)
参数1.任务,
参数2.延迟时长数字(第一次执行在什么时间之后)
参数3.周期时长数字(每隔多久执行一次)
参数4.时长数字的单位.TimeUnit的常量指定(秒)
本文详细介绍了线程与进程的区别、线程调度机制、同步与异步的概念、并发与并行的区别、多线程实现方式及线程池的使用方法等多线程核心技术。同时还深入探讨了线程安全问题及其解决办法。
746

被折叠的 条评论
为什么被折叠?



