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>>
    

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("买到烟,把烟给老爸..");
}

}

猜你喜欢

转载自blog.csdn.net/PussyCatsss/article/details/92006886