多线程,同步机制,锁

多线程

1. 多线程

1.1 基本概念:程序、进程、线程

程序(program)是为完成特定任务、用某种语言编写的一组指令的集合
一段静态的代码,静态对象。

进程(process)是程序的一次执行过程,或是正在运行的一个程序
一个动态的过程:有它自身的产生、存在和消亡的过程。——生命周期

线程(thread),进程可进一步细化为线程,是一个程序内部的一条执行路径。
线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc)

1.2 单核CPU和多核CPU的理解

a) 单核CPU,其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程 的任务。
b) 一个Java应用程序java.exe,其实至少有三个线程:main()主线程,gc() 垃圾回收线程,异常处理线程。当然如果发生异常,会影响主线程。

1.3 并行与并发

单线程其实是比多线程效率高的,因为多线程需要线程切换,比较耗费资源,只不过多线程给用户的响应时间要快

并发:单核来讲,一个CPU接收到很多的请求,这些请求只能一个个执行,此时多个请求的情况就被称之为并发;当然多核也是可以发生并发情况的;
并行:针对多核来讲,两个或两个以上的CPU同时接收到许多请求,而每个CPU都可以执行一个请求,并且这个执行是在同时进行的,两个或两个以上CPU同一时间执行请求,被称之为并行;当然,如果请求足够多,CPU每个都有执行的请求,其余的请求就得排队执行,这时排队等待执行的情况就被称之为多线程并发,当然这些请求都是同一时间发出的。

1.4 使用多线程优点

提高应用程序的响应。对图形化界面更有意义,可增强用户体验。
提高计算机系统CPU的利用率
改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和
修改

1.5 何时需要多线程

程序需要同时执行两个或多个任务;
程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等;
需要一些后台运行的程序时;

1.6 创建方式

创建线程有两种方式,但是启动线程只有一种方式,就是调用线程对象中的start()方法

1.6.1 继承

第一种 : 继承Thread类并覆写run()方法

Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread
类来体现。

Thread类的特性
每个线程都是通过某个特定Thread对象的run()方法来完成操作的,经常 把run()方法的主体称为线程体
通过该Thread对象的start()方法来启动这个线程,而非直接调用run()

构造器
Thread():创建新的Thread对象
Thread(String threadname):创建线程并指定线程实例名
Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接
口中的run方法
Thread(Runnable target, String name):创建新的Thread对象

创建过程
继承Thread类
1)定义子类继承Thread类。
2)子类中重写Thread类中的run方法。
3)创建Thread子类对象,即创建了线程对象。
4)调用线程对象start方法:启动线程,调用run方法。

1.6.2Runnable

第二种创建线程的方式 : 实现Runable接口并覆写run()方法
启动还是使用线程对象中的start()方法

1.7 继承和实现的区别

继承Thread:线程代码存放Thread子类run方法中
实现Runnable:线程代码存在接口的子类的run方法。

实现方式的好处
避免了单继承的局限性
多个线程可以共享同一个接口实现类的对象,非常适合多个相同线 程来处理同一份资源。

1.8 常用方法

start() : 启动线程唯一方式
setName( ) : 设置线程的名字,默认是 Thread-0 , Thread-1 … 以此类推
getName( ) : 获取线程的名字
setPriority() : 设置线程优先级
getPriority() : 获取线程优先级
static currentThread() : 获取当前线程的内存地址(获取当前线程对象)
static sleep() : 让当前线程进入睡眠,参数是毫秒数

1.9 时间片分配

Java的调度方法
同优先级线程组成先进先出队列(先到先服务),使用时间片策略
对高优先级,使用优先调度的抢占式策略

1.10. 优先级使用

优先级 : java中分为10个等级,分别是1-10

在Thread类中还提供了三个常量,分别保存1,5,10 优先级
最高 : 10 Thread.MAX_PRIORITY
正常 : 5 Thread.NORM_PRIORITY
最低 : 1 Thread.MIN_PRIORITY

getPriority() : 获取该线程优先级
setPriority() : 设置该线程优先级

线程创建时继承父线程的优先级Thread的优先级是5
低优先级只是获得调度的概率低,并非一定是在高优先级线程之后才被调用

1.11生命周期

概述

创建 --> 就绪 --> 运行 --> 阻塞 --> 复活 --> 阻塞… --> 死亡

JDK中用Thread.State类定义了线程的几种状态

新建: 当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建 状态

就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件,只是没分配到CPU资源

运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态, run()方法定义了线 程的操作和功能

阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出 CPU 并临时中止自己的执行,进入阻塞状态
死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束

static currentThread() : 静态方法,用于获取当前线程的对象,
写在哪个线程中,就获取哪个线程的对象

static sleep(long m) : 静态方法,让当前线程睡眠,
需要传入对应的毫秒数,写在哪个线程就睡眠哪个线程

1.12线程控制

Interrupt() : 强制唤醒某一个线程 会报错噢~

sleep() 让当前线程睡眠

唤醒睡眠的线程有两种方式
1 正常唤醒 : 就是睡眠时间到了
2 异常唤醒 : 强制打断睡眠,会报异常

1.13 Join

Join : 线程合并,让指定线程在该线程运行完之后再执行

1.14 Yield

Thread.yeild : 暂停当前正在执行的线程,并执行其他线程
1 静态方法,意味着写在哪个线程 , 哪个线程就让位
2 给相同的优先级线程让位,不同优先级不让位
3 该当前线程执行的执行的时候(拿到了时间片),把该执行机会(时间片) 让给其他线程

1.15 stop

stop : 终止一个线程,容易出现问题,不太安全,不推荐使用
可以使用标识符的形式来结束

1.16线程同步机制

当多个线程操作同一个数据的时候,为了保证数据的一致
线程同步本质就是数据同步,是一种安全机制

异步编程 : 线程之间是完全独立的,谁的运行也不会受到别的线程的影响

同步编程 : 线程之间不是独立的,相互之间是有影响的,某个功能必须必只能让一个线程同时执行,主要为了数据安全

同步的原因 :
数据同步,为了数据安全,某种情况来讲,同步可以理解为暂时把多线程转换为单线程

只要对方法加上 synchronized的成员方法,就代表该方法不能被多个线程同时访问

锁是每个对象都有的,synchronized只是把锁锁住的一个持续动作,而多个线程必须保存同一个对象,才能使用同一把锁,才能相互排斥,才能保证数据安全

如果多个线程之间保存的不是同一个对象,尽管是同一个类的不同对象,也是没有办法相互排斥的

解决方案
对于多线程的安全问题提供了专业的解决方式:同步机制
1.同步代码块:
synchronized (对象){
// 需要被同步的代码;
}

2.synchronized还可以放在方法声明中,表示整个方法为同步方法。
例如:
public synchronized void show (String name){
….
}

1.17 Lock

从JDK 5.0开始,Java提供了更强大的线程同步机制——通过显式定义同
步锁对象来实现同步。同步锁使用Lock对象充当。

java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的 工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象 加锁,线程开始访问共享资源之前应先获得Lock对象。

ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和 内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以 显式加锁、释放锁。

1.17 synchronized 与 Lock 的对比

1.Lock是显式锁(手动开启和关闭锁,别忘记关闭锁),synchronized是 隐式锁,出了作用域自动释放
2.Lock只有代码块锁,synchronized有代码块锁和方法锁
3.使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有
更好的扩展性(提供更多的子类)

优先使用顺序:
Lock 同步代码块(已经进入了方法体,分配了相应资源)同步方法
(在方法体之外)

猜你喜欢

转载自blog.csdn.net/MIRACLE_Ying/article/details/113362504