多线程
Process 与 thread
程序:程序是指令和数据的有序结合,其本身没有任何运行的含义,是一个静态的概念
进程:是执行程序的一次过程,他是一个动态的概念,是系统资源分配的单位
线程:通常在一个进程中可以包含多个线程,一个进程中至少有一个线程,不然没有存在的意义,。
线程是CPU调度和执行的单位
注意:很多多线程是模拟出来的,真正的多线程是指有多个CPU,即多核,如服务器;
如果模拟出来的多线程在一个CPU下,在同一个时间点,CPU只能执行一段代码,因为切换得快,就有同时执行的错觉。
并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。
并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。
区别:并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机系统中,每一时刻却仅能有一道程序执行,故微观上这些程序只能是分时地交替执行。倘若在计算机系统中有多个处理机,则这些可以并发执行的程序便可被分配到多个处理机上,实现并行执行,即利用每个处理机来处理一个可并发执行的程序,这样,多个程序便可以同时执行
线程就是独立的执行路径
在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程
main()称为主线程,为系统的入口,用于执行整个程序
在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统密切相关的,先后顺序是不能人为干预的
对同一个资源操作时,会出现资源抢夺的问题,需要加入并发控制;
线程会带来额外的开销,如CPU调度时间,并发控制开销
每个线程在自己的工作内存交互,内存控制不当会造成数据不一致
继承thread:
创建线程的方式, 继承thread类 重写run方法 调用start开启线程
实现Runnable接口:
创建线程对象,通过线程对象开启我们的线程
Callable:
实现callable 接口,需要返回值类型
重写call方法,需要抛出异常
创建目标对象
创建执行服务:ExecutorServeice ser = Executors.newFixedThreadPool(1);
提交执行 Future<Boolean> result1 = ser.submit(t1);
获取结果 boolean r1 = result.get();
关闭服务:ser.shutdownNow();
Lambda 表达式
线程
创建 :new
就绪:start()
运行:
阻塞:sleep wait
死亡;
sleep (时间) 指定当前线程阻塞的毫秒数
sleep 存在异常
sleep 时间到达后线程进入就绪状态
sleep 可以模拟网络延时,倒计时等
每一个对象都一个锁,sleep不会释放锁
Yield
线程礼让:让当前正在执行的线程暂停,但不阻塞
将线程从运行状态转换为就绪状态
让CPU重现调度,礼让不一定成功,看CPU心情
线程死亡后就不能在start了 要重新创建 new
priority 线程的优先级,这是个是控制权重的 1-10
setPriority
线程的优先级低 知识说明CPU调度的概率低,但是也有可能调到
守护线程 daemon
线程分为用户线程和守护线程
thread.setDaemon(true) 默认是false 表示用户线程,正常的线程都是用户线程
由于统一进程的多个线程共享同一个存储空间,在带来方便的同时,也带来了访问冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入锁机制synchronized,当一个线程获得对象的排它锁,独占资源,其它线程必须等待,使用后释放锁即可,存在以下问题:
一个线程持有锁会导致其它所有需要此锁的线程挂起
在多线程竞争下,加锁,释放锁会导致比较多的上下文切换 和 调度延时,引起性能问题;
如果一个优先级高的线程等待一个优先级低的线程释放锁, 会导致优先级倒置,引起性能问题
同步方法:synchronized:方法一旦执行,就独占该锁,直到该方法返回才释放
同步块:synchronized (obj){}
obj:称为同步监视器
obj可以是任何对象,但是推荐使用共享资源作为同步监视器,
同步方法中无需指定同步监视器,因为同步方法的同步监视器就是this,就是这个对象本身,或者时class
LOCK
ReentrantLock : lock.lock() ; lock.unlock();
线程协作
wait 等待
notify 唤醒
sleep 抱着锁睡觉
管程法:就是弄一个缓冲区,生产者生产好的放在缓冲区,消费者去拿
信号灯法:设置一个标志flag true or false
好处:便于线程管理
corePoolSize:核心池的大小
maxiumumPoolSize: 最大线程数
浙公网安备 33010602011771号