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,涉及安全问题,待改进...

浙公网安备 33010602011771号