一.多线程
线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
多进程是指操作系统能同时运行多个任务(程序)。
多线程是指在同一程序中有多个顺序流在执行。
在java中要想实现多线程,有两种手段,一种是继承Thread类,另外一种是实现Runable接口
1.继承Thread类
使用方法:
继承Thread类或实现Runable接口
重写run方法
主线程main在main()调用时候被创建。随着调用MitiSay的两个对象的start方法,另外两个线程也启动了
2.实现Runable接口
实际上所有的多线程代码都是通过运行Thread的start()方法来运行的
run()方法是多线程程序的一个约定。所有的多线程代码都在run方法里面。Thread类实际上也是实现了Runnable接口的类。
3.Thread和Runnable的区别
如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
实现Runnable接口比继承Thread类所具有的优势:
1:适合多个相同的程序代码的线程去处理同一个资源
2:可以避免java中的单继承的限制
3:增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
4:线程池只能放入实现Runable,不能直接放入继承Thread的类
4.线程状态转换
5.线程调度
线程的调度
1、调整线程优先级:Java线程有优先级,优先级高的线程会获得较多的运行机会。
线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。
6.常用函数说明
①sleep(long millis): 在指定的毫秒数内让当前正在执行的线程暂停执行。Thread.sleep(long millis)方法,使线程转到阻塞状态。millis参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为就绪(Runnable)状态。sleep()平台移植性好。
②join():指等待t线程终止。。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。
③yield():暂停当前正在执行的线程对象,并执行其他线程。
Thread.yield()方法作用是:暂停当前正在执行的线程对象,并执行其他线程。
7.线程同步
synchronized关键字的作用域:
是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)
1、线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他非同步方法
2、对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁,当在一个同步方法中访问另外对象上的同步方法时,会获取这两个对象锁。
3、对于同步,要时刻清醒在哪个对象上同步,这是关键。
二.泛型与容器类
泛型的基本概念
泛型的本质就是“数据类型的参数化”,处理的数据类型不是固定的,而是可以作为参数传入。我们可以把“泛型”理解为数据类型的一个占位符(类似形式参数),即告诉编译器,在调用泛型时必须传入实际类型,这种参数类型可以在类,接口和方法中,分别被称泛型类、泛型接口、泛型方法。
泛型的好处:
代码可读性更好(不需要强制转换)
程序更加安全(只要编译时期没有警告,运行时期就不会出现ClassCastException异常)
类型擦除:
编码时采用泛型写的类型参数,编译器会在编译时去掉,这称之为“类型擦除”。
泛型的使用:
定义泛型
泛型字符可以是任何标识符,一般采用几个标记:E、T、K、V、N、?
泛型类:
泛型类就是把泛型定义在类上,用户使用该类的时候,才把类型明确下来。泛型类的具体使用方法是在类的名称后添加一个或多个类型参数声明,如<T><T,K,V>
语法块:
public class 类名 <泛型表示符号>{
}
泛型接口:
泛型接口与泛型类的声明方式一致。泛型接口的具体类型需要在实现类中进行声明。
语法块:
public interface 接口名<泛型表示符号>{
}
泛型方法:
泛型方法是指将方法的参数类型定义成泛型,以便在调用时接受不同类型的参数。类型参数可以有多个,用逗号隔开,如<K,V>。定义时,类型参数一般放到返回值的前面。
调用泛型方法中,不需要像泛型类那样告诉编译器是什么类型,编译器可以自动推断出类型来。
语法块:
public <泛型表示符号> void getName (泛型表示符号 name ){}
public<泛型表示符号> 泛型表示符号 getName (泛型表示符号 name){}
无界通配符:
“ ? ”表示类型通配符,用于替代具体的类型,它只能在“<>”中使用。可以解决当具体类型不确定的问题。
语法块:
public void showFlag(Generic<?> generic){
}
容器
Java提供的一套容器类,其中基本类型是List、Set(集)、Queue和Map(映射),这些对象类型也称之为集合类。
列表( List ):数组方式实现,维护元素的索引顺序
– 对象按索引存储
– 可以存储重复元素
主要实现类
– ArrayList:动态数组
•遍历比较快,插入删除偏慢
– LinkedList:链表
•双向链表,遍历速度慢,快速插入删除
集合和数组之间的转换问题
//1.把集合(List,Set)转换为数组
Object[] objs=set.toArray();
//2.把数组转换成集合(List),需要依靠Arrays工具实现
List<Object> list=Arrays.asList(objs);
集(Set)是最简单的一种集合:
关心唯一性
–对象无序存储
–不能存储重复元素,不维护元素的索引顺序
主要实现类:HashSet:使用被插入对象的Hash码(效率最高),无序,不是同步的,底层通过散列函数来进行元素的存储。
LinkedHashSet:继承于HashSet、又基于LinkedHashMap来实现,遍历性能比HashSet好,以元素插入的顺序来维护集合的链接表,在散列函数的基础上添加了链表支持。
TreeSet:二叉树结构(通过红黑树生成二叉排序树),保证元素按照元素的自然顺序进行升序排序,添加操作速率比散列集慢,访问和遍历的时间很快
Queue接口:
– java.util.Queue
队列是一种特殊的线性表,只允许在表的前端(front,队头)进行删除操作,而在表的后端(rear,队尾)进行插入操作
LinkedList实现了Queue接 口
Map接口:
对象以键-值对(key-value)存储
key不允许有重复,value允许有重复
Map中元素,可以将key序列、value序列单独抽取出来
–使用keySet()抽取key序列,将map中的所有keys生成一个Set。
–使用values()抽取value序列,将map中的所有values生成一个Collection。(通常转成list)
原文链接:https://blog.csdn.net/weixin_63816398/article/details/123587241