A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Summer丶time 初级黑马   /  2018-12-12 11:22  /  841 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Day1 Object类,常用API
1.        直接打印对象名字名字就是调用toString方法;
2.        看着一个类是否重写了toString方法,直接打印这个类对应对象名字即可,如果没有重写,那么打印的就是对象的地址值,如果重写了就按照重写的方式打印;
3.        equals指示某个对象是否与出对象相等;
4.        “==”  基本数组类型:比较的是值
1.        引用数据类型:比较的是地址值;
5.        equals 一般用于比较两个对象的内容; == 比较基本类型的值和对象的地址
a)        一般字符串之间的比较 用equals();
6.        类型转化异常关键字:instanceof;
7.        使用“=”赋值符号直接创建的String 可以使用”==”也可以用equals,new出来的字符串只能用equals比较;
8.        null不能调用方法,会出现空指针异常;
9.        gettime() 把日期转换为毫秒;
a)        空参构造就是获取当前时间;
b)        有参构造(毫秒l),将毫秒转成时间;
10.        dateformat是一个将日期/时间格式化子类的抽象类;
11.        simpledateformat(String pattern) 构造模式;
a)        写对应的模式,会把模式替换为对应的日期和时间;
b)        模式中的字母不能改变,但连接的字母符号可以改变;
12.        format方法经日期格式化为文本dateformatdateformat
a)        parse方法把文本解析为日期
b)        parse方法声明了一个解析异常:如果字符串和构造方法中的模式不一样,那么程序就会抛出此异常,解决这个异常,一名throws继续声明这个异常,要么try..catch自己处理这个异常;
13.        calendar是一个抽象类,里面提供了很多操作日历字段的方法
a)        无法直接使用。里面有个一静态方法叫getinstance,返回了一个子类对象;
14.        currenttimemillis():返回衣毫以为单位的当前时间;
a)        arraycopy(obkect src,int srcpos,object dest,int dest psost,in length)
b)        src-源数组
c)        srcpos-源数组起始位置
d)        dest-目标数组
e)        destpost-目标数组起始位置
f)        length-要复制元素的数量
15.        Stringbuilder类 字符串缓冲区,可以提高字符串的操作效率(看成一个长度可以变化的字符串)底层也是一个数组,但没有被final修饰,可以改变长度
16.        append方法往Stringbuilder添加数据
a)        返回值是this,就是调用方法的对象,使用该方法无需接受返回值
b)        链式编程:方法的返回值是一个对象,可以根据对象继续调用方法;
17.        toString方法可以将Stringbyilder与String相互转换
a)        String->Stringbuilder:可以使用Stringbuilde构造方法;
b)        Stringbuilder->String可以使用Stringbuilder 的toString方法;
18.        基本数据类型的数据没有对应的方法来操作这些数据,所有我们可以使用一个类,把基本数据类型包装起来,这个类叫包装类,包装类可以定义一些方法,用来操作数据。
19.        Integer 比较-128 127 之间地址值相同可用“==”
Day2 Collection、泛型
1.        集合的存储对象都是对象,集合长度不固定;数组储存的都是同一类元素,既可以是基本数据也可以是元素,数组长度固定不可变。
2.        学习集合目标:
a)        会使用集合储存数据
b)        会遍历集合,把数据取出来
c)        掌握每种集合的特性
3.        继承:子类共性抽取形成父类(接口)
a)        List接口
i.        有序的集合(储存元素和取出元素的顺序是一致
ii.        允许重复重复的元素
iii.        有索引,包含以下带索引的方法
b)        Set接口
i.        不允许重复重复元素
ii.        没有索引,不包含带索引的方法
4.        Collection接口:定义的是所有单列集合中共性的方法,所有单列集合都可以使用(不包含带索引的方法),所有单列集合最顶层的接口
a)        集合框架的学习方法:
i.        学习顶层:学习顶层(接口/抽象类)中共性方法,所有的子类都可以使用
ii.        使用底层:顶层不是接口就是抽象类,不能创建对象,需要使用底层子类对象使用
b)        Collection共性方法:
i.        add:把给定对象添加岛当前集合中(返回值是一个boolean值,一般都是true,不用接收)
ii.        remove:把给定的对象在当前集合中删除(返回值是一个boolean值,如果集合中存在元素,删除元素,返回true;集合中不存在元素,删除失败,返回false;集合中有相同元素,只会删除第一个)
iii.        contains: 判断当前集合中是否包含给定的对象(返回值是一个boolean值,包含返回true,不包含返回false)
iv.        isEmpty(): 判断当前集合是否为空(返回值是一个boolean值,集合为空返回true,不为空返回false;集合为空,集合存在)
v.        int size(): 返回集合中元素的个数(返回值是int值)
vi.        Object[] toArray(): 把集合中的元素,存储到数组中(返回值是是一个Object类型的数组)
vii.        void clear() :清空集合中所有的元素(没有返回值,不会把集合删除,集合还可以继续使用)
5.        Iterator迭代器(范型等同于集合,用于对集合进行遍历)
a)        hasNext():是否到达集合的末尾
b)        E next():取出集合中的元素
c)        Itertor 是一个接口,我们无法直接使用,需要使用Iterator接口实现类;获取方法比较特殊,接口中有一个方法叫iterrator(),这个方法返回的就是它的实现类对象
d)        使用步骤(发现使用迭代器取出集合中元素的代码,是一个重复的过程,所以我们可以使用循环优化,不知道集合中有多少元素,使用while循环,循环结束的条件,hasNext方法返回false):
i.        使用集合中的方法iterator(),获取迭代器的实现类对象,使用Iterator接口接收实现类(多态)
ii.        使用Iterator接口中的方法hasNext判断是否到达了集合的末尾
iii.        使用Iterator接口中的方法next取出集合中的元素
e)        迭代器原理:
i.        创建迭代器时获取迭代器的实现类对象,会把指针(索引)指向集合的第一个元素(0索引)
ii.        While 循环中判断是否到达集合的末尾
iii.        循环体内部:
1)        取出指针指向的元素;
2)        把指针向后移动一位
f)        迭代器并发修改异常:
i.        使用迭代器的过程中,修改了集合的长度(添加,删除了元素),就会抛出这个异常(并发:1.迭代;2.修改长度)
ii.        并发修改异常的解决并发:
1)        在迭代中不对长度进行修改
2)        了解:Iterror 有一个子接口listIterator接口(只有list接口下边的集合可用)该接口定义了add和remove方法,可以对集合添加和删除元素,如果使用了该接口中的add和remove方法就不会抛出该异常(将修改值同步到迭代器)
g)        增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作
格式:
   for(元素的数据类型 变量 : Collection集合or数组){
//写操作代码
}
6.        泛型:是一种未知的数据类型,当不知道什么数据类型可以时,可以使用泛型,泛型也可以看作是一个变量,用来接受数据类型
a)        创建对象的时候,就会确定泛型的数据类型。会把数据类型作为参数转递给泛型E
i.        E e:Element 元素
ii.        T t:Type    类型
b)        泛型的好处:
i.        创建集合对象,使用泛型
好处:
1)        避免了类型转换的麻烦,存储数据是什么类型,取出数据就是什么类型
2)        把运行期异常(代码运行之后会抛出异常),提升到了编译期(写代码的时候会报错)
弊端:
1)        泛型是什么类型,只能存储什么类型的数据
ii.        创建集合对象,不使用泛型
好处:
1)        集合不使用泛型,默认的数据类型就是Object类型,可以存储任意数据类型的数据
弊端:
1)        不安全,会引发异常
c)        泛型的定义及使用
i.        定义一个含有泛型的类,模拟ArrayList集合
ii.        泛型是一个未知的数据类型,当我们不确定什么什么数据类型的时候,可以使用泛型
iii.        泛型可以接收任意的数据类型,可以使用Integer,String,Student...(修饰)
iv.        创建对象的时候确定泛型的数据类型
v.        定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间
格式:
     修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){
          方法体;
     }
含有泛型的方法,在调用方法的时候确定泛型的数据类型
递什么类型的参数,泛型就是什么类型
vi.        含有泛型的接口
1)        第一种使用方式:
定义接口的实现类,实现接口,并且直接指定接口的泛型
2)        第二种使用方式:
                     接口使用什么泛型,实现类就使用什么泛型,类跟着接口走
                     就相当于定义了一个含有泛型的类,创建对象的时候确定泛a型的数据类型
vii.        泛型通配符“?”
1)        ?:代表任意的数据类型
2)        使用方法:
        不能创建对象使用
        能作为方法的参数使用
viii.        泛型的限定:
1)        上限限定:? extends E 代表使用的泛型只能是E类型的子类/本身:
2)        下限限定: ? super E 代表使用的泛型只能是E类型的父类/本身:
Day3 集合List、Set、Collections
一、        数据结构
1        常见的数据结构
A        栈:(先进后出) 储存元素岛集合:入/压栈;取出集合中元素:出/弹栈
B        队列:(先进先出)  
C        数组
I        特点:
1)        查询快:数据的长度时连续的,我们通过数据的首地址就可以找到数组,通过数组的索引值可以快速查找某一个元素
2)        增删慢:数值的长度时固定的,我们想要增/删一个元素,就必须创建一个新数组把源数组的数据复制过来(在堆内存中频繁的创建新数组,造成效率低下)
D        链表 linked list


I        特点
1)        查询慢:链表中的地址不是连续的,每次查询元素都必须从头开始查询
2)        增删快:链表结构增/删一个元素,对链表的整体结构没有影响,所以增删快
II        分类:
1)        单向链表:链表中只有一个链子,不能标准元素的顺序(储存和取出元素顺序可能不一致)
2)        双向链表:链表中有两台链子,有一条链子专门记录元素的顺序,是一个有序的集合
E        红黑树 binary tree
I        分类
1)        树形结构、计算机中的树(倒着):树根;分支;树叶
2)        二叉树:分支不能超过两个:左孩子/左子树;右孩子/右子树
3)        排序树/查找树:在二叉树的基础上,元素有大小顺序的。左子树小,右子树大
4)        平衡树:左孩子和右孩子相等
5)        不平衡树:左孩子不等于右孩子
II        特点
1)        趋近于平衡术,查询速度非常快,查询叶子节点最大次数和最小次数不能超过两倍
III        约束
1)        节点可以是红色或者黑色
2)        根节点是黑色
3)        叶子节点(空节点)时黑色的
4)        每个红色节点的子节点都是黑色的
5)        任何一个节点到每个叶子节点的所有路径的黑色节点数相同
二、        List集合(接口        Collection的子类)
1        特点
A        有序的集合(储存元素和取出元素的顺序是一致)
B        允许重复重复的元素
C        有索引,包含以下带索引的方法
2        List接口中的常用方法:
A        public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上
B        public E get(int index) :返回集合中指定位置的元素。
C        public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素
D        public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素
3        遍历List集合三种方式:
I        普通的for循环
II        迭代器
III        增强for
4        注意:操作时注意越界异常
三、        List集合的子类
1        ArrayList集合
A        特点:
I        底层是Object数组(查询快;增删慢)赋值的方式(System.arraycopy)来处理数组的增长
II        当容量不足时,其扩容的方式时:先将容量扩充至当前的容量的1.5倍,若还不够扩充至当前需要的数量(grow方法)
III        多线程
2        LinkedList 集合
A        特点:
I        底层是一个链表结构(查询慢,增删快)
II        里面包含大量操作首尾元素的方法
III        多线程
B        注意:使用LinkedList方法不能使用多态
C        主要方法
I        public void addFirst(E e) :将指定元素插入此列表的开头
II        public void push(E e) :等效于addFiest
III        public void addLast(E e) :等效于add方法,将指定元素添加到此列表的结尾
IV        public E getFirst() :返回此列表的第一个元素
V        public E getLast() :返回此列表的最后一个元素
VI        public E removeFirst() :移除并返回此列表的第一个元素
VII        public E pop() :等效于removeFirst方法
VIII        public E removeLast() :移除并返回此列表的最后一个元素
IX        public boolean isEmpty() :如果列表不包含元素,则返回true
3        Vector集合
A        特点:JDK1.0中的集合底层也是数组
B        单线程
四、        Set接口:
1        Set特点:
A        Set接口和List接口一样,同样继承自 Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了
B        Set接口中元素无序
C        没有索引,没有带索引的方法,也不能用普通的for循环方法遍历
2        HashSet特点:
A        Set接口中元素无序
B        没有索引,没有带索引的方法,也不能用普通的for循环方法遍历(使用迭代器遍历/增强for)
C        是一个无序的集合,储存和取出的顺序可能不一致
D        底层是一个哈希表结构(查询速度非常快)
3        哈希表
A        原理(见下图):
B        Set集合不允许重复元素的原因

4        运用HashSET存储自定义元素
A        要求:存储的元素,必须重写hashCode和equals方法以保证同属性被视为同一对象
5        LinkedHashSet
A        特点:底层是一个哈希表(数组+链表/红黑表)与一个链表:多一条链表(记录元素的储存顺序),保证元素有序
6        可变参数:JDK1.5之后出现的新特性
A        使用前提:当方法的参数列表数据类型已经确认,但是参数个数不确定,就可以使用可变参数
B        使用格式:定义方法时使用 修饰符 返回值类型 方法名(数据类型…变量名){ }
C        可变参数原理:
I        底层就是一个数组,根据传递参数的个数不同,就会创建出不同的数组,来存储这些参数
II        传递参数的个数,可以实0个()不传递,到多个
D        注意事项
I        一个方法的参数列表,只能有一个可变参数
II        如果方法的参数有多个,呢么可变参数必须卸载参数列表的末尾
III        可变参数的终极写法:Object…变量名
五、        Collections集合工具类
1        常用方法
A        public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素
B        public static void shuffle(List<?> list) 打乱顺序 :打乱集合顺序
C        public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序(
I        默认是升序,注意:被被排序的的集合里存储的元素,必须实现Comparable,重写compareTo排序的规则:
II        自己(this)-参数:升序;参数-自己(this)降序
D        public static <T> void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则
I        o1-o2 升序;02-o1降序
II        new Comparator<E>
Day4 集合Map、HashMap
I.        Map集合
A.        概述:双列集合(Collection: 单列集合)
1.        双列集合(Collection: 单列集合),一个元素包含两个值
2.        Map结合中的元素,key和value的数据类型可以相同,也可以不同
3.        Map key不允许重复,value是可以重复的
4.        key和value是一一对应
B.        Map集合的主要子类
1.        HashMap<k,v>集合,imlements map<k,v>接口
a.         特点
1.        底层是哈希表:查询速度快
2.        HashMao集合是一个无需的结合,存储和取出元素的顺可能不一致
2.        LinkedHashMap
a.        特点:
1.        底层是哈希表+链表
2.        有序
C.        Map接口中的常用方法:
1.        public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。
a.        存储键值对的时候,key不重复,返回值v是null
b.        存储键值对的时候,key重复,会使用新的value替换map中重复的value,返回被替换的value值
2.        public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
3.        public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
4.        boolean contaionsKey():判断集合中是否包含指定的键
5.        public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。
6.        public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。
D.        遍历元素
1.        键找值方法(见图一 二)
a.        public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。
b.        遍历集合Set集合,得到每一个key
c.        通过Map.gei()方法,用kay拿到value

图一

图二
2.        Map.Entry:

图三

图四
3.        Entry
a.        实现步骤
1.        使用Map集合中的enstrset(),把Map结合中多个Entry对象取出来,储存到一个Set集合中
2.        遍历Set结合,获取每一个Entry对象
3.        使用Entry对象中的方法getKey()和getValue()获取键与值
4.        HashMap储存自定义类型的键与值
a.        作为key的元素必须重写hashCode和equals方法,以保证Key值唯一
5.        LinkeHashMap集合
a.        相较于HashMap集合是一个有序的集合
6.        Hashtable集合
a.        底层也是一个哈希表,是一个线程安全的集合,是单线程集合,速度慢
b.        HashMap底层哈希表,线程不安全,多线程,速度快
c.        HashMap(之前学的所有的集合):可以储存null、null键/Hashtable不能储存null值、null键
d.        Hashtabel和Vector集合一样,在jdk1.2之后被(HashMap和,ArrayList)取代了
Day5 异常、线程
1.        异常
a)        异常的概念:指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
b)        异常体系异常机制其实是帮助我们找到程序中的问题,异常的根类是 java.lang.Throwable ,其下有两个子类:java.lang.Error 与 java.lang.Exception ,平常所说的异常指 java.lang.Exception 。
i.        Error:严重错误Error,无法通过处理的错误,只能事先避免,好比绝症。
ii.        Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的。好 比感冒、阑尾炎
c)        异常分类:
i.        编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)
ii.        运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。(如数学异 常)
d)        异常处理
i.        往上抛,最终抛给虚拟机交给虚拟机处理(打印异常信息;中断程序,后面的代码也不会指向)
ii.        Try{}catch(){}处理异常,处理完之后程序继续执行,不会停止
e)        异常产生解析
2.        异常的处理
a)        throw关键字
i.        作用:在指定的方法在指定的方法中抛出指定的异常
ii.        使用格式: throw new xxxExceotion(”异常产生的原因”)
1.        throw关键字必须写在方法的内部
2.        throw关键字后边new的对象必须是Exception或者Exception的子类对象
3.        throw关键字抛出指定的异常对象,我们就必须处理这个异常对象
a)        throw关键字后边创建的是RuntimeException或者是 RuntimeException的子类对象,我们可以不处理,默认交给JVM处理(打印异常对象,中断程程序
b)        throw关键字后边创建的是编译异常(写代码的时候报错),我们就必须处理这个异常,要么throws,要么try...catch
iii.        throw:写在方法内,我们自己抛异常,我可以直接定义异常的信息
iv.        throws:写在方法上,JVM帮我们抛异常,使用默认的异常信息
b)        Objects非空判断  requireNonNull方法
c)        throws关键字
i.        作用:当方法内部抛出异常对象的时候那我们就必须处理这个异常对象,可以使用throws关机子处理异常对象,会把异常对象声明抛出给方法的调用者处理,最终交给JVM处理(中断处理)
ii.        使用格式:方法声明时使用
修饰符 返回值类型 方法名(参数列表) thows aaaExcepition,bbbExcopition…{
  throw new aaaExcepition(“产生的原因”)
  throw new bbbExcepition(“产生的原因”)
  …
iii.        注意
1.        throws关键字必须写在方法声明处
2.        throws关键字后边声明的异常必须是Exception或者是Exception的子类
3.        方法内部如果抛出了多个异常对象,那么throws后边必须也声明多个异常,如果抛出的多个异常对象有子父类关系,那么直接声明父类异常即可
4.        调用了一个声明抛出异常的方法,我们就必须的处理声明的异常,要么继续使用throws声明抛出,交给方法的调用者处理,最终交给JVM,要么try...catch自己处理异常
d)        try...catch
i.        作用:助理异常的第二种方式,自己处理
ii.        格式:
     try{
         可能产生异常的代码
     }catch(定义一个异常的变量,用来接收try中抛出的异常对象){
           异常的处理逻辑,异常常量对象之后,字母处理异常对象
            一般工作中,会把异常储存到日志中
     }
     …
     catch(异常类名 变量名){
     }
iii.        注意:
1.        try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象
2.        .如果try中产生了异常,那么就会执行catch中的异常处理逻辑,执行完毕catch中的处理逻辑,继续执行try...catch之后的代码;如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑,执行完try中的代码,继续执行try...catch之后的代码
e)        trowable:throwable类中定义了3个异常处理的方法
i.        String getMessage() 返回此 throwable 的简短描述
ii.        String toString() 返回此 throwable 的详细消息字符串
iii.        void printStackTrace()  JVM打印异常对象,默认此方法,打印的异常信息是最全面的
f)        finally 代码块
i.        作用:
     finaliy中的代码无论如何都会被执行的
ii.        格式:
     try{
         可能产生异常的代码
     }catch(定义一个异常的变量,用来接收try中抛出的异常对象){
           异常的处理逻辑,异常常量对象之后,字母处理异常对象
            一般工作中,会把异常储存到日志中
     }
     …
     catch(异常类名 变量名)
     }finally{
     }
iii.        注意
1.        Finally不能单独使用,必须和try一起使用
2.        Finally一般用于资源释放(资源回收),无论程序师傅出现异常,最后都要资源释放(IO)
g)        异常的处理事项
i.        多异常的处理:
1.        多个分别处理
2.        多个异常一次捕获,多次处理
a)        一个try多个catch注意事项
i.        catch里面定义的异常变量,如果有子父类关系,那么子类的异常变量必须写在上面否则就会报错
如果try中出现了异常对象,会把异常对象抛给catch处理,抛出的异常对象,会从上到下依次赋值给catch中的异常变量
3.        多个异常一次捕获,一次处理
4.        运行时异常抛出可以不处理。即不捕获也不声明
ii.        finally中有return语句
1.        finally有return语句,永远返回finally中的结果,避免该情况
iii.        子父类异常:
1.        如果父类抛出了多个异常,子类重写父类方法时,抛出父类相同的异常或者时异常的父类异常的子类或者不抛出异常
2.        父类没有抛出异常,子类重写父类该方法时也不可以抛出异常。此时子类产生该异常,只能捕获异常,不能声明抛出
h)        自定义异常类
i.        概述:
     java提供的异常类,不够我们使用,需要自己定义一些异常类
ii.        格式:
public class XXXExcepiton extends Exception | RuntimeException{
   添加一个空参数的构造方法
   添加一个带异常信息的构造方法
iii.        注意
1.        自定义异常类一般都是以Exception结尾,说明该类是一个异常类
2.        自定义异常类,必须的继承Exception或者RuntimeException
a)        继承Exception:那么自定义的异常类就是一个编译期异常,如果方法内部抛出了编译期异常,就必须处理这个异常,要么throws,要么try...catch
b)        继承RuntimeException:那么自定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理(中断处理)
3.        多线程
a)        并发与并向
i.        并发(交替执行):指多个事件在同一时间段内发生
ii.        并行(同时执行):多个时间在同一时刻发生(同时发生)

b)        线程与进程
i.        进程:指一个内存中运行的应用程序,进入到内存的程序叫进程

ii.        线程时进程中的一个执行单元

c)        线程调度
i.        分时调度
ii.        抢占式调度
   优先让优先级高的线程执行
d)        主线程
i.        执行主线程(main)方法的线程,java之中只有一个主方法,从上至下依次执行
e)        Threa类创建多线程的第一种方式
i.        内容 创建多线程的第一种方法:创建Thread类的子类
     我们要想实现多线程,就必须继承Thread
ii.        实现步骤
1.        创建一个Thread类的子类
2.        在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么?)
3.        创建Thread类的子类对
4.        调用Thread类中的方法start方法,开启新的线程,执行run方法
void start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
结果是两个线程并发地运行;当前线程(main线程)和另一个线程(创建的新线程,执行其 run 方法)。
多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。
java程序属于抢占式调度,那个线程的优先级高,那个线程优先执行;同一个优先级,随机选择一个执行
Day6 多线程之同步
1.        线程
a)        多线程原理
i.        随机性打印结果
ii.        多线程内存图解
iii.        Thread类中的常用方法
1.        获取当前线程的名称
a)        获取当前线程的名称:getname()
b)        可以先获取当前正在执行的线程,使用getname获取当前线程的名称:
static thread currrent        thread() 返回对当前正在执行的线程对象的引用
2.        设置线程的名称
a)        setname(String)方法
b)        通过有参构造
3.        sleep方法
a)        Thread.sleep(long)
iv.        创建线程中的第二种方式:Runnable接口
1.        介绍:Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为 run 的无参数方法
a)        Thread(Runnable target) 分配新的 Thread 对象
b)        Thread(Runnable target, String name) 分配新的 Thread 对象
2.        实现方法
a)        创建一个Runnable接口的实现类
b)        在实现类中重写Runnable接口的run方法,设置线程任务
c)        创建一个Runnable接口的实现类对象
d)        创建Thread类对象,构造方法中传递Runnable接口的实现类对象
e)        调用Thread类中的start方法,开启新的线程执行run方法
3.        实现Runnable接口创建多线程程序的好处:
a)        避免了单继承的局限性
一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类;
实现了Runnable接口,还可以继承其他的类,实现其他的接口
b)        增强了程序的扩展性,降低了程序的耦合性(解耦)
实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离(解耦);
实现类中,重写了run方法:用来设置线程任务;
创建Thread类对象,调用start方法:用来开启新线程
2.        线程安全
a)        线程安全
i.        概述:多线程访问共享数据
ii.        线程安全问题产生的原理





iii.         线程同步:
1.        同步代码块
a)        格式 synchronized(锁对象){
         可能出现线程安全问题的代码(访问了共享数据的代码)
          }
b)        注意:
i.        通过代码块中的锁对象,可以使用任意的对象
ii.        但是必须保证多个线程使用的锁对象是同一个
iii.        锁对象作用: 把同步代码块锁住,只让一个线程在同步代码块中执行
2.        同步方法
a)        格式:修饰符 synchronized 返回值类型 方法名(参数列表){
         可能会出现线程安全问题的代码(访问了共享数据的代码)
       }
b)        使用步骤:
i.        把访问了共享数据的代码抽取出来,放到一个方法中
ii.        在方法上添加synchronized修饰符
c)        静态同步方法
锁对象是谁?
不能是this;this是创建对象之后产生的,静态方法优先于对象,静态方法的锁对象是本类的class属性-->class文件对象(反射)
3.        Lock锁
a)        方法
i.        void lock()获取锁
ii.        void unlock()  释放锁
b)        使用步骤
i.        在成员位置创建一个ReentrantLock对象
ii.        在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
iii.        在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁


3.        线程的状态
a)        进入到TimeWaiting(计时等待)有两种方式
i.        使用sleep(long m)方法,在毫秒值结束之后,线程睡醒进入到Runnable/Blocked状态
ii.        使用wait(long m)方法,wait方法如果在毫秒值结束之后,还没有被notify唤醒,就会自动醒来,线程睡醒进入到Runnable/Blocked状态
b)        唤醒的方法:
i.        void notify() 唤醒在此对象监视器上等待的单个线程
ii.        void notifyAll() 唤醒在此对象监视器上等待的所有线程







0 个回复

您需要登录后才可以回帖 登录 | 加入黑马