Map:
-
存储键值对形式的数据 key-value(K-V)
-
key是无序的,不可重复的-->set集合
-
value无序的,可重复的 -->Collection集合
-
一个key只能对应一个value(如果想要value对应多个值可以存储在容器中list)
-
存储多个数据的时候,如果key相同,value会覆盖
- 遍历:
-
keySet() 返回所有的key
-
values() 返回所有的值
-
entrySet() Set<Map.Entry<K,V>>
ollections 操作于容器的工具类
void sort(List) //对 List 容器内的元素排序,按照升序进行排序。
void shuffle(List) //对 List 容器内的元素进行随机排列
void reverse(List) //对 List 容器内的元素进行逆续排列
void fill(List, Object) //用一个特定的对象重写整个 List 容器
int binarySearch(List, Object)//采用折半查找的方法查找特定对象
如何处理HashMap的线程安全问题:
1.Hashtable
2.Collections.synchronizedMap(Map) 返回一个线程安全的map容器
3.juc包下java.util.concurrent 类 ConcurrentHashMap<K,V> 线程安全的容器HashMap容器类==>推荐使用:效率高
多线程:
-
多个任务同时执行就是多线程,如果不需要多任务,就不需要开启多线程
-
优点:资源利用率更好;程序设计在某些情况下更简单;程序响应更快
-
进程:对与操作系统而言就是不同的任务执行,每一个进行都有自己的代码和数据空间,进程之间切换消耗比较大,一个进程中包含一刀多个线程,是资源分配的最小单位
-
线程:一系列线程共享代码和数据空间,线程之间切换消耗较小,线程是cpu调度的最小单位
-
三高: 高可用(数据不会出错) 高性能(用户体验度好) 高并发(多用户同时操作抢购)
-
关注重点:
-
1.多线程的创建方式
-
1)继承Thread类 重写run()方法
-
2)实现Runnable接口,重写run()方法 --推荐
-
3)实现Callable接口,重写call()方法--了解 juc
-
2.保证线程安全问题 同步
-
3.线程状态
-
1)继承Thread类 重写run()方法
-
开启线程:Thread->start()开启线程
2)实现Runnable接口,重写run()方法 --推荐
-
好处:避免带线程的局限性 实现资源共享
-
开启线程:使用Tread类中的start()方法开启 (静态代理)
==========================================================================================
/*第三种开启多线程的方式:
-
实现Callable接口,重写call方法
-
优点:可以抛出异常,可以存在返回值
-
缺点:使用麻烦
*/
public class MatchDemo05 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建线程
ExecutorService ser=Executors. newFixedThreadPool (2);
Match02 match=new Match02();
Future<Integer> step1=ser.submit(match);
Future<Integer> step2=ser.submit(match);
//获取call方法的返回值
int i1=step1.get();
int i2=step1.get();
//结束服务
ser.shutdown();
}
}
// 龟兔赛跑类
class Match02 implements Callable{
//存储赢了人的姓名
String winner=null;
@Override
public Integer call() throws InterruptedException {
for(int steps=1;steps<=100;steps++){
if("兔子".equals(Thread.currentThread().getName()) && steps%10==0){
Thread.sleep(5);
}
System.out.println(Thread.currentThread().getName()+"跑了第"+steps+"步");
boolean flag=check(steps); //返回值true,停止循环,停止游戏
if(flag){
return steps;
}
}
return null;
}
/*
* 判断循环是否停止
* 返回值:返回true,存在胜利者
* 否则返回false
*/
public boolean check(int steps){
if(winner!=null){
return true;
}else{
if(steps==100){
winner=Thread.currentThread().getName();
return true;
}
}
return false;
}
}
==========================================================================================
线程的状态:
- 新生状态 : new,每个线程都有自己的运行空间
- 就绪状态 : start(),就绪不代表运行,代表线程具有可运行的能力,在就绪队列中排队等待cpu调度
- 运行状态 : cpu把时间片分配给某个线程,这个线程就就行运行状态
- 阻塞状态 : sleep()…
- 终止状态 : 执行完毕
- 注意:
- 1)一个线程一旦进入到阻塞状态,阻塞解除无法直接回复运行状态,进入就绪状态等待cpu的调度
- 2)一旦一个线程以终止,无法恢复,如果创建开启,也是新的线程
- 终止状态的几种情况:
- 1)正常执行完毕
- 2)强制结束 stop(),destroy(),方法已过时,不推荐使用
- 3)通过标识进行控制–推荐
- 进入就绪状态的情况:
- 1.start()
- 2.阻塞状态结束
- 3.yield()
- 4.线程切换,被切换的线程进入到就绪状态
- 进入阻塞状态的情况:
- 1.sleep()
- 2.wait()
- 3.join()
- 4.IO操作
/
/ - sleep方法:
- 1.方法问题的可能性
- 2.模拟网络延时
*/
public class StateDemo02 {
public static void main(String[] args) {
new Thread(()->{
for(int i=10;i>=0;i–){
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(i);
}
}).start();
}
}
=============================================================================================
/*yield() 高风亮节 礼让线程 */
public class YieldDemo {
public static void main(String[] args) {
Demo d=new Demo();
new Thread(d,“A”).start();
new Thread(d,“B”).start();
}
}
class Demo implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-------start()");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"-------end()");
}
}
=============================================================================================
/*
- join() 插队
*/
public class JoinDemo {
public static void main(String[] args) {
new Thread(new Father()).start();
}
}
class Father implements Runnable{
@Override
public void run() {
System.out.println("突然想抽烟了...");
System.out.println("给儿子100块钱,让儿子去买烟....");
//开启儿子线程
Thread th=new Thread(new Son());
th.start();
//儿子线程插队,父亲线程等待
try {
th.join();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("儿子丢了,找儿子去...");
}
System.out.println("接过烟,抽一口...");
System.out.println("零钱给儿子...");
}
}
class Son implements Runnable{
@Override
public void run() {
System.out.println("结果钱去买烟....");
System.out.println("路上遇到一个游戏厅,玩10s钟....");
for(int i=1;i<=10;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i+"秒钟过去了...");
}
System.out.println("买到烟,把烟给老爸..");
}
}