Day25-进程和线程

进程和线程

书接上回:Map集合

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * 特点:称为“映射”存储一对数据(Key-Value),键不可重复,值可以重复。
 * V put(K key,V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。 
	Object get(Object key) //根据键获取对应的值。
	Set<K> keySet()//返回所有key。
	Collection<V> values() //返回包含所有值的Collection集合。
	Set<Map.Entry<K,V>> entrySet() //键值匹配的Set集合。
 *
 */
public class TestMap {
	public static void main(String[] args) {
		//创建集合
		Map<String,String> map=new HashMap<String,String>();
		//添加元素
		map.put("cn", "中国");
		map.put("usa", "美国");
		map.put("uk", "英国");
		map.put("usa", "美利坚共和国");
		map.put("China", "中国");
		System.out.println("元素个数:"+map.size());
		System.out.println(map);
		System.out.println(map.keySet());
		System.out.println(map.values());
		System.out.println(map.get("usa"));
		//删除元素
//		map.remove("uk");
//		System.out.println("元素个数:"+map.size());
//		System.out.println(map);
//		map.clear();
//		System.out.println("元素个数:"+map.size());
	
		//遍历元素
		//1通过键找值
		System.out.println("先遍历键通过键取值:");
		Set<String> keySet=map.keySet();
		for(String key:keySet) {
			System.out.println(key+"---------"+map.get(key));
		}
		System.out.println("====================================");
		Iterator<String> it=keySet.iterator();
		while(it.hasNext()) {
			String str=it.next();//map集合中的每个键
			System.out.println(str+"----------"+map.get(str));//map.get(str)通过键找值
		}
		System.out.println("====================================");
		//2直接遍历键值对
		System.out.println("遍历一组键值对:");
		Set<Entry<String,String>>  entrySet=map.entrySet();
		for(Entry<String,String> entry:entrySet) {
//			System.out.println(entry);
			System.out.println(entry.getKey()+"========"+entry.getValue());
		}
		Iterator<Entry<String,String>> entry2= entrySet.iterator();
		while(entry2.hasNext()) {
			Entry<String,String> en=entry2.next();
//			System.out.println(en);
			System.out.println(en.getKey()+"&"+en.getValue());
		}
		//判断元素
		System.out.println(map.containsKey("cn"));
		System.out.println(map.containsValue("中国"));
		System.out.println(map.isEmpty());
	}
}

Map接口

概念与特点:

存储一对数据(Key-value),无序、无下标、键不可重复,值可重复

  • HashMap

存储结构:哈希表(数组+链表)

源码分析

拿到任何一个对象后,通过hash(key)做运算,key>>>(除以16),

只可能得到0~15之间的一个数组,作为插入数组的下标

import java.util.Objects;

public class Student {
	private String name;
	private int age;
	
	public Student() {
		super();
		
	}
	
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	//重写,去重
	@Override
	public int hashCode() {
		return Objects.hash(age, name);
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		return age == other.age && Objects.equals(name, other.name);
	}
	
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

public class TestStudent {
	public static void main(String[] args) {
		//创建集合对象
//		通过接口new实现类和通过通过实现类new实现类有何区别
		//项目开发中,一般通过接口new实现类,
		//键:一个学生,值:地址
		HashMap<Student, String> hashMap = new HashMap<Student, String>();
		
		//添加元素
		Student s1 = new Student("张三",18);
		Student s2 = new Student("李四",18);
		Student s3 = new Student("王二麻子",19);
		Student s4 = new Student("张三",18);
		
		hashMap.put(s1, "北京");
		hashMap.put(s2, "上海");
		hashMap.put(s3, "广州");
		hashMap.put(s4, "深圳");
		System.out.println("元素个数:"+hashMap.size());
		System.out.println(hashMap);
		
//		//删除元素
//		hashMap.remove(s1);
//		System.out.println("元素个数:"+hashMap.size());
//		System.out.println(hashMap);
//		//清空
//		hashMap.clear();
//		System.out.println("元素个数:"+hashMap.size());
		
		//遍历元素
		System.out.println("通过遍历key遍历value");
		
		//1、获得Key 通过Key找Value
		Set<Student> keySet = hashMap.keySet();
		
		System.out.println("通过增强for循环遍历:");
		//左边泛型 右边集合名
		for (Student student : keySet) {
			System.out.println(student+"-----"+hashMap.get(student));
		}
		
		System.out.println("通过迭代器遍历:");
	 	Iterator<Student> iterator = keySet.iterator();
		while (iterator.hasNext()) {
			Student student = iterator.next();
			System.out.println(student+"-----"+hashMap.get(student));
		}
		
		//2、直接遍历map集合
		Set<Entry<Student, String>> entrySet = hashMap.entrySet();
		
		System.out.println("通过增强for循环遍历:");
		for (Entry<Student, String> entry : entrySet) {
//			直接输出
//			System.out.println(entry);
			//单独输出,获得key和value
			System.out.println(entry.getKey()+"-----"+entry.getValue());
		}
		
		System.out.println("通过迭代器遍历:");
		Iterator<Entry<Student, String>> iterator2 = entrySet.iterator();
		while (iterator2.hasNext()) {
			Entry<Student, String> entry = (Entry<Student, String>) iterator2.next();
//			System.out.println(entry);
			System.out.println(entry.getKey()+"-----"+entry.getValue());
		}
		
		//判断元素
		System.out.println(hashMap.containsKey(s2));
		//Map覆盖掉了北京,所有为false
		System.out.println(hashMap.containsValue("北京"));
		System.out.println(hashMap.isEmpty());
	}
	
}
  • LinkedHashMap

LinkedHashMap继承于HashMap

  • TreeMap

自动对key做排序,根据compareTo的返回值去重

public class Student {
	private String name;
	private int age;
	
	public Student() {
		super();
	}
	
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
}

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
/**
 * TreeMap :
实现了SortedMap接口(Map的子接口),可以对key自动排序,Key需实现Comparable接口。
 */
public class TestStudent {
	public static void main(String[] args) {
		//类内处理
		
		//类外处理
		Comparator<Student> comparator = new Comparator<Student>() {

			@Override
			public int compare(Student o1, Student o2) {
				// TODO Auto-generated method stub
				return o1.getAge() - o2.getAge();
			}
		
		};
		
		//创建集合
		TreeMap<Student, String> treeMap = new TreeMap<Student, String>(comparator);
		
		//添加元素
		Student s1 = new Student("张三",18);
		Student s2 = new Student("李四",20);
		Student s3 = new Student("王二麻子",19);
		Student s4 = new Student("张三",18);
		
		treeMap.put(s1, "北京");
		treeMap.put(s2, "上海");
		treeMap.put(s3, "广州");
		treeMap.put(s4, "深圳");
		System.out.println("元素个数"+treeMap.size());
		System.out.println(treeMap);
		
//		//删除元素
//		treeMap.remove(s1);
//		System.out.println("元素个数"+treeMap.size());
//		treeMap.clear();
//		System.out.println("元素个数"+treeMap.size());
		
		//遍历元素
		System.out.println("通过key遍历value");
		Set<Student> keSet = treeMap.keySet();
		System.out.println("通过增强for循环遍历");
		for (Student student : keSet) {
			System.out.println(student+"-----"+treeMap.get(student));
		}
		System.out.println("通过迭代器遍历");
		Iterator<Student> iterator = keSet.iterator();
		while (iterator.hasNext()) {
			Student student = iterator.next();
			System.out.println(student+"-----"+treeMap.get(student));
		}

		System.out.println("直接遍历map集合");
		Set<Entry<Student, String>> entry = treeMap.entrySet();

		System.out.println("通过增强for循环遍历");
		for (Entry<Student, String> entry2 : entry) {
//			System.out.println(entry2);
			System.out.println(entry2.getKey()+"-----"+entry2.getValue());
		}
		System.out.println("通过迭代器遍历");
		Iterator<Entry<Student, String>> iterator2 = entry.iterator();
		while (iterator2.hasNext()) {
//			System.out.println(entry2);
			Entry<Student, String> next = iterator2.next();
			System.out.println(next.getKey()+"-----"+next.getValue());
		}
		//判断元素
	}
}
  • Hashtable

HashMap的线程安全版本

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

public class TestHashtable {
	public static void main(String[] args) {
		// 创建集合对象
//	   HashMap<Student,String> hashMap=new HashMap<Student,String>();
		Hashtable<Student, String> hashMap = new Hashtable<Student, String>();
		// 添加元素**
		Student s1 = new Student("张三", 18);
		Student s2 = new Student("李四", 20);
		Student s3 = new Student("王二麻子", 19);
		Student s4 = new Student("张三", 18);
		hashMap.put(s1, "北京");
		hashMap.put(s2, "上海");
		hashMap.put(s3, "广州");
		hashMap.put(s4, "深圳");
//				hashMap.put(null, null);
		System.out.println("元素个数:" + hashMap.size());
		System.out.println(hashMap);
		// 删除元素
//				hashMap.remove(s1);
//				System.out.println("元素个数:"+hashMap.size());
//				System.out.println(hashMap);
//				hashMap.clear();
//				System.out.println("元素个数:"+hashMap.size());
		// 遍历元素**
		// 1通过key找value
		System.out.println("通过遍历key进而遍历value");
		Set<Student> keySet = hashMap.keySet();
		System.out.println("通过增强for循环遍历:");
		for (Student stu : keySet) {
			System.out.println(stu + "-----------" + hashMap.get(stu));
		}
		System.out.println("通过迭代器遍历:");
		Iterator<Student> it = keySet.iterator();
		while (it.hasNext()) {
			Student stu = it.next();
			System.out.println(stu + "-----------" + hashMap.get(stu));
		}
		// 2直接遍历map集合
		System.out.println("直接遍历Map集合");
		Set<Entry<Student, String>> entrySet = hashMap.entrySet();
		System.out.println("通过增强for循环遍历:");
		for (Entry<Student, String> entry : entrySet) {
//					System.out.println(entry);
			System.out.println(entry.getKey() + "---------" + entry.getValue());
		}
		System.out.println("通过迭代器遍历:");
		Iterator<Entry<Student, String>> it2 = entrySet.iterator();
		while (it2.hasNext()) {
			Entry<Student, String> entry = it2.next();
//					System.out.println(entry);
			System.out.println(entry.getKey() + "---------" + entry.getValue());
		}
		// 判断元素
		System.out.println(hashMap.containsKey(s2));
		System.out.println(hashMap.containsValue("北京"));
		System.out.println(hashMap.contains("北京"));
		System.out.println(hashMap.isEmpty());
	}
}
  • Properties

Hashtable 子类,主要用于存储key和value都是字符串的情况,常在读取配置文件之后,保存文件中的键值对。反射、JDBC

import java.util.Properties;
import java.util.Set;
/**
 * Properties使用方式
 * 特点:
 *    1.存属性名与属性值
 *    2.属性名与属性值都是字符串类型
 *    3.没有泛型
 *    4.与流有关****
 *
 */
public class TestProperties {
	public static void main(String[] args) {
		//创建集合对象
		//没有泛型
		Properties properties = new Properties();
		
		//添加元素
		properties.setProperty("name", "tom");
		properties.setProperty("age", "18");
		properties.setProperty("address", "北京");
		System.out.println("元素个数:"+properties.size());
		System.out.println(properties);
		
		
		//删除元素
		properties.remove("address");
		System.out.println("元素个数:"+properties.size());
		System.out.println(properties);

		//遍历元素...
		//通过keySet()...
		//通过entrySet()...
		//返回所有的属性名
		System.out.println("返回所有的属性名:");
		Set<String> proString = properties.stringPropertyNames();
		System.out.println("增强for循环遍历:");
		for (String string : proString) {
			System.out.println(string+"-----"+properties.getProperty(string));
		}
		
		//判断元素
		System.out.println(properties.containsKey("name"));
		System.out.println(properties.containsValue("name"));
		System.out.println(properties.isEmpty());
		
		//System
		System.out.println("--------------------");
		Properties properties2 = System.getProperties();
		Set<String> strings = properties2.stringPropertyNames();
		for (String string : strings) {
			System.out.println(string+"----"+properties2.getProperty(string));
		}
	}
}

多线程

进程

概念:运行时的程序,系统资源分配的基本单位

线程

概念:轻量级的进程,系统运行调度的基本单位

进程和线程的区别

进程是操作系统资源分配的基本单位,而线程是CPU的基本调度单位。

一个程序运行后至少有一个进程。

一个进程可以包含多个线程,但是至少需要有一个线程。

进程间不能共享数据段地址,但同进程的线程之间可以。

线程的组成

任何线程都具备基本的组成部分:CPU时间片,运行数据,线程的逻辑代码

创建线程的两种方式

一、通过继承创建进程

二、通过实现Runnable接口创建线程

/**
 * 龟兔赛跑
 * 实质:两个线程交替获取CPU执行权
 * 
 * 一、通过继承创建进程
 * 1、创建线程:写个类继承Thread方法,重写run方法
 * 2、启动线程:创建线程对象,通过对象名.start()开启线程
 * 3、线程中的基本方法
 * 
 * 优点:编程简单
 * 缺点:java是单进程的,已经继承Thread类无法继承其他类
 * 	
 * 
 */
public abstract class TestThread {
	//主方法作为兔子线程
	public static void main(String[] args) {
		//创建子线程
		TortoiseThread tortoiseThread = new TortoiseThread();
		
		tortoiseThread.start();
		
		
		while (true) {
			Thread.currentThread().setName("兔子线程");
			System.out.println("兔子领先了>>>>"+Thread.currentThread().getName());
		}
	}
}

/**
 * 乌龟线程
 */
public class TortoiseThread extends Thread{

	@Override
	public void run() {
		this.setName("乌龟线程");
		while (true) {
			System.out.println("乌龟领先了!!!!"+this.getName());
		}
	}
	
}

/**
 * 二、通过实现Runnable接口创建线程
 * 优点:可以继承其他类 资源共享
 * 缺点:编程稍微复杂
 */
public class TestRunnable {
	public static void main(String[] args) {
		//创建乌龟线程
		TortoiseRunnable tortoiseThread = new TortoiseRunnable();
		Thread tt = new Thread(tortoiseThread);
		tt.setName("小乌龟线程");
		tt.start();
		
		Thread.currentThread().setName("兔子线程");
		while (true) {
			System.out.println("兔子领先了>>>>"+Thread.currentThread().getName());
		}
	}
}

public class TortoiseRunnable implements Runnable{

	@Override
	public void run() {
		while (true) {
			System.out.println("乌龟领先了!!!!"+Thread.currentThread().getName());
		}
	}

}

一些使用

public class RunnerThread extends Thread{
	private String rname;
	public RunnerThread() {
		
	}
	public RunnerThread(String rname,String name) {
//		this.setName(name);
		super(name);
	}
	@Override
	public void run() {
		while (true) {
			System.out.println(rname+"领先了>>>>"+this.getName());
		}
	}
	
}

public class TestThread {
	public static void main(String[] args) {
		//创建选手线程
		RunnerThread rt1 = new RunnerThread("刘翔","刘翔线程");
		RunnerThread rt2 = new RunnerThread("苏炳添","苏炳添线程");
		RunnerThread rt3 = new RunnerThread("博尔特","博尔特线程");
		
		//启动线程
		rt1.start();
		rt2.start();
		rt3.start();
	}
}

模拟12306售票

public class TicketThread extends Thread{
	private int tikNum = 100;

	
	public TicketThread(String name) {
		super(name);
	}


	@Override
	public void run() {
		while (tikNum > 0) {
			//售票
			System.out.println(this.getName()+"窗口,卖了第"+tikNum+"张票");
		}
		tikNum--;
	}
	
}

/**
 * 模拟12306售票
 * 4个窗口
 */
public class TestTicket {
	public static void main(String[] args) {
		//创建四个窗口
		TicketThread tt1 = new TicketThread("一号窗口");
		TicketThread tt2 = new TicketThread("二号窗口");
		TicketThread tt3 = new TicketThread("三号窗口");
		TicketThread tt4 = new TicketThread("四号窗口");
	}
}

可以发现,这样写有bug,改进

public class TicketRunnable implements Runnable{
	private int tikNum = 100;
	@Override
	public void run() {
		while(tikNum>0) {
			//售票
			System.out.println(Thread.currentThread().getName()+"窗口,卖了第"+tikNum+"张票");
			//票数减一
			tikNum--;
		}
	}

}

public class TestTicket {
	public static void main(String[] args) {
		//创建四个窗口线程
		TicketRunnable tt=new TicketRunnable();
		Thread t1=new Thread(tt,"一号窗口");
		Thread t2=new Thread(tt,"二号窗口");
		Thread t3=new Thread(tt,"三号窗口");
		Thread t4=new Thread(tt,"四号窗口");
		//启动线程
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

这样写好了很多,但还有一点小bug,涉及安全问题,待改进...

posted @ 2021-08-05 20:02  CN_Darren  阅读(52)  评论(0)    收藏  举报