java--Map容器和多线程
Map接⼝
特点:
存储键值对形式的数据 key-value(K-V)
key是⽆序的,不可重复的–>set集合
value⽆序的,可重复的 -->Collection集合
⼀个key只能对应⼀个value(如果想要value对应多个值可以存储在容器中list)
存储多个数据的时候,如果key相同,value会覆盖
遍历⽅法:
keySet() 返回所有的key
values() 返回所有的值
entrySet() Set<Map.Entry<K,V>> 返回此映射包含的映射关系Set视图
常⽤的⽅法有:
V put(K key, V value)将指定的值与此映射中的指定键关联(可选操作)。返回被覆盖的value值,如果没有相同key的键值对,返回null V get(Object key)返回指定键所映射的值,如果此值不包含该键的映射关系,则返回null
V remove(Object key) 如果存在⼀个键的映射关系,则从此映射中移除此映射(可选操作)
boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value) 如果此映射将⼀个或者多个键映射到指定值,则返回true
HashMap容器类
特点:线程是不安全的,底层是由哈希表实现的,hashmap去重是根据key去重,⾃定义引⽤数据类型数据时去重需要重写
hashcode()和equals()⽅法。
Hashtable容器类和HashMap容器类类似,但是它的线程是安全的。
TreeMap容器类
底层:由红⿊树实现的。
TreeMap去重:根据key去重,⾃定义引⽤数据类型时,需要指定内部⽐较器或者外部⽐较器。
注意:
如果想要根据key去重做某种规则的排序选择TreeMap,否则选择HashMap
Collections操作容器的⼯具类
void sort(List) //对 List 容器内的元素排序,按照升序进⾏排序。
void shuffle(List) //对 List 容器内的元素进⾏随机排列
void reverse(List) //对 List 容器内的元素进⾏逆续排列
void fill(List, Object) //⽤⼀个特定的对象重写整个 List 容器
int binarySearch(List, Object)//采⽤折半查的⽅法查特定对象
如何处理HashMap的线程安全问题:
1. Hashtable
1. Hashtable
2. Collections.synchronizedMap(Map) 返回⼀个线程安全的map容器
3. juc包下urrent 类 ConcurrentHashMap<K,V> 线程安全的容器HashMap容器类==>推荐使⽤:效率⾼Properties类
特点:K-V都是字符串形式的数据。主要⽤作配置⽂件使⽤。
配置⽂件的步骤:src右键->new source folder->new file->db.properties->键值对形式的数据
多线程
多个任务同时执⾏就是多线程,如果不需要多任务,就不需要开启多线程。
优点:资源利⽤率更好;程序设计在某些情况下更简单;程序响应更快。
进程:对于操作系统⽽⾔就是不同的任务执⾏,每⼀个进程都有⾃⼰的代码和数据空间,进程之间切换消耗⽐较⼤,⼀个进程中包含⼀到多个线程,是资源分配的最⼩单位
线程:⼀系列线程共享代码和数据空间,线程之间切换消耗较⼩,线程是cpu调度的最⼩单位
关注的重点:
1. 多线程的创建⽅式
1)继承Thread类,重写run()⽅法。开启线程Thread->start()开启线程
2)实现Runable接⼝,重写run()⽅法。开启线程Thread->start()开启线程。
好处:可以避免单线程的局限性,实现资源共享。(静态代理模式)
3)实现Callable接⼝,重写call()⽅法。
优点:可以抛出异常,可以存在返回值
缺点:使⽤⿇烦
2. 保证线程安全问题(同步)
3. 线程状态
线程的状态
新⽣状态 : new,每个线程都有⾃⼰的运⾏空间
就绪状态 : start(),就绪不代表运⾏,代表线程具有可运⾏的能⼒,在就绪队列中排队等待cpu调度
运⾏状态 : cpu把时间⽚分配给某个线程,这个线程就是运⾏状态
阻塞状态 : sleep()…
终⽌状态 : 执⾏完毕
注意:
1)⼀个线程⼀旦进⼊到阻塞状态,阻塞解除后⽆法直接恢复运⾏状态,会进⼊就绪状态等待cpu的调度
2)⼀旦⼀个线程已经终⽌,将⽆法恢复,如果创建开启,也是新的线程
终⽌状态的⼏种情况:
1)正常执⾏完毕
2)强制结束 stop(),destroy(),⽅法已过时,不推荐使⽤
3)通过标识进⾏控制–推荐
3)通过标识进⾏控制–推荐
进⼊就绪状态的情况:
1)start()
2)阻塞状态结束
3)yield() ⾼风亮节,礼让线程。
4)线程切换,被切换的线程进⼊到就绪状态
进⼊阻塞状态的情况:
1)sleep()
2)wait()
3)join()插队
4)IO操作
sleep⽅法:
1)放⼤问题的可能性
2)模拟⽹络延时
线程安全问题:
多线程同时操作同⼀份资源的时候,有可能出现线程不安全问题
处理线程安全:
同步锁 synchronized
同步⽅法: 效率较低,简单
同步静态⽅法
同步成员⽅法
同步块: synchronized(this|类名.calss|资源(成员属性)){…}
注意:
1.锁⼀定要锁不变的内容 ,⾃定义类型对象地址
2.锁的范围太⼤,效率低,锁的范围太⼩锁不住
double check 双重检查 效率⾼,锁的范围⼩
锁静态⽅法,锁类的class对象都是锁类,锁住了这个类的所有对象
锁资源,效率较⾼,注意⼀定要锁不变的资源内容。
最好使资源变成⾃定义类型–>锁对象的地址肯定不变,才能保证安全
锁this:锁住对象所有的资源(成员属性),如果只想锁住某⼀个资源,那就可以直接就锁资源
线程通信
object类中有三个⽅法,在线程通信中会经常⽤到,wait() 和notify()和notifyAll()。wait():使线程进⼊等待序列,释放对象锁,让出cpu 的资源。notify()和notifyAll():唤醒对⽅处于等待序列的线程,具有可运⾏的能⼒,并且要获取对象的锁和cpu的资源才能运⾏,如果被唤醒的线程没有获取对象锁⽆法执⾏。
一个线程可以包含多个进程void wait() -在其他线程调⽤此对象的 notify() ⽅法或 notifyAll() ⽅法前,导致当前线程等待。
void notify() 唤醒在此对象监视器上等待的单个线程 。如果所有线程都在此对象上等待,则会选择唤醒其中⼀个线程。选择是任意性的。
void notifyAll() 唤醒在此对象监视器上等待的所有线程。 被唤醒的线程将以常规⽅式与在该对象上主动同步的其他所有线程进⾏竞争。
注意:只能在同步环境下使⽤ 否则会产⽣异常IllegalMonitorStateException。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论