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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 养只猫叫冰棍儿 初级黑马   /  2018-11-20 16:22  /  785 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Day03——Day06
栈:
特点:先进后出,入口和出口在同一侧
入栈(压栈):将元素存入栈


出栈(弹栈):将元素从栈中取出

队列:
特点:先进先出,入口和出口在两侧

数组:
特点:查询快,增删慢
(通过第一个元素值+索引可以快速的计算出该索引的地址值;
增加一个元素,要创建长度+1的新数组,然后将原数组元素复制到新数组,然后存入新元素)

链表:由多个节点组成
单向链表:每个节点存储数据和下一节点的地址值
双向链表:每个节点存储数据、上一节点地址值和下一节点地址值
链表的特点:查询慢增删快
(要找的其中某个节点,只能从第一个节点一个一个向后寻找
只需要修改保存的下一个节点的地址值,就可以快速完成增删)

红黑树:
是一种平衡二叉查找树
平衡:
左子节点和右子节点数量相同
二叉:
每个节点至多有两个子节点
查找:
节点存储的元素是按照大小顺序存储的
特点:
元素存储过程中就完成了大小排序
查询比链表快,增删比数组快(数组和链表的折中)
List集合体系特点:
1.元素存取有序(存入和取出元素的顺序一致)排序:从小到大
2.元素可以重复
3.有索引
ArrayList底层的数据结构:数组
ArrayList的特点:
1、查询快 2、增删慢 3、线程不安全,效率高
LinkedList底层的数据结构:链表
LinkedList的特点:
1、查询慢 2、增删快 3、线程不安全,效率高




Set集合体系特点:
1. 元素不可重复
2. 没有索引
HashSet特点:
1. 元素不可重复
2. 没有索引
3. 元素存取无序 (存入和取出顺序有可能不一致)
4. 底层采用 哈希表 结构. (查询快)
  哈希表 = 数组 + 链表或红黑树
HashSet集合保证添加元素不重复的原理:
调用 add(E e) 添加元素时, 先调用 hashCode() 获取哈希值, 和当前HashSet集合中的元素比较
  如果哈希值不同, 则认为元素不重复, 添加, 并返回true
  如果哈希值相同, 则可能是哈希冲突, 所以继续调用元素的 equals() 方法和所有哈希值相同的元素比较
   如果 equals() 比较所有元素都没有相同的, 则认为元素不重复, 添加, 并返回true
   如果 equals() 比较出有相同的元素, 则认为元素  重复, 不添加, 并返回false
自定义JavaBean对象实现在HashSet中去重:
JavaBean默认继承Object类中的 hashCode() 和   equals() 方法, 都是根据对象地址值判断是否重复的
要根据属性值判断是否重复, 应该在JavaBean类中  重写 hashCode() 和 equals() 方法, 使其按照属性  值比较
LinkedHashSet特点:
1. 元素存取有序 (存入和取出顺序一致)
2. 元素不可重复
3. 没有索引
LinkedHashSet底层数据结构:
哈希表 + 链表   (也就是: 数组 + 链表或红黑树 + 链表)
其中, 哈希表用于存储数据, 额外的链表用于记录元素添加时的先后顺序, 以便在获取元素时保持顺序一致
什么时候用List, 什么时候用Set?
   存储的元素可以重复的, 用List集合:
    增删少, 用ArrayList
    增删多, 用LinkedList  
   要存储的数据要求不重复, 或者相对一个集合去重, 用Set集合:
    不要求存取顺序一致, 用HashSet
    要求存取顺序一致, 用LinkedHashSet

sort(List<T> list): 默认按照"升序"将元素排序
数字, 字母, 都可以按照升序排序

自定义JavaBean对象
默认不能排序, 因为不知道如何比较哪个对象大, 哪个对象小
自定义JavaBean对象要想排序, 需要实现 Comparable<E> 接口, 重写 int compareTo(E e) 方法
规则:
  this-参数: 升序(从小到大)
  参数-this: 降序(从大到小)
Comparable接口和Comparator接口区别
Comparable: 让JavaBean自身具有可比较性 (自己和其他人比)
Comparator: 定义一个比较器类, 用比较器对象比 (让第三个人来帮两个人比较)
Comparator使用方式:
1. 定义类实现Comparator<E>接口, 重写 int compare(E o1, E o2) 方法, 泛型为比较元素的类型
  规则:
            o1-o2: 升序(从小到大)
            o2-o1: 降序(从大到小)

2. 在Collections.sort(List<T>list,Comparator<? super T> c)方法中传入自定义比较器对象
∆ Map
Map遍历方式一:keySet(方法实现通过键找值)
Set<K> keySet(): 获取Map集合中所有的键, 存储到Set集合中

keySet()遍历步骤:
1. Map对象调用 keySet() 方法, 获取包含所有key的Set集合
2. 遍历Set集合, 获取每个key
3. 通过Map对象调用 get(Object key) 方法根据key获取到value
例:Map<String, String> map = new HashMap<>();
// keySet()遍历
Set<String> keys = map.keySet();
for (String key : keys) {
  // 通过每个键获取值
  String value = map.get(key);
  // 打印当前键值对
  System.out.println(key + "=" + value);
}
java.util.Map接口
Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)

Map遍历方式2:通过entrySet()获取Entry对象形式遍历
LinkedHashMap底层: 哈希表 + 链表
key不允许重复, 但key存取有序
Hashtable和HashMap:
相同点:
  1. 底层都是哈希表
不同点:
  1. Hashtable不允许存储 null 值和 null 键; HashMap允许存储 null 值和 null 键
  2. Hashtable线程安全效率
低; HashMap线程不安全效率高
Hashtable目前很少使用.
但其子类 Properties 集合, 可以与IO流结合使用
, 应用较多

∆异常:

指的是程序在执行过程中, 出现的非正常的情况, 最终会导致JVM的非正常停止
注意:在Java中, 每种异常都有对应的"类"来描述. 发生了一个异常, 就是出现了这个异常类的"对象"
  异常不是语法错误

错误(Error): 不能捕获处理的严重问题. 绝症
必须将程序停下来, 修改代码才能解决
错误的类名都是 "XxxError" 方式
异常(Exception): 可以捕获处理的问题. 发烧感冒吃个药就好了
程序执行起来后, 如果有合适的处理方式, 即使发生异常, 程序也能处理该异常并继续运行
异常的类名都是 "XxxException" 方式
1. 编译时异常:
  编译时期就会发生的异常, 必须在编译时期处理  Unhandled exception XxxException
2. 运行时异常:
  编译时正常, 运行时才会发生的异常

throw关键字作用:

在方法中抛出指定的异常对象
格式:
throw new 异常类名("异常原因字符串");
例:throw new ArrayIndexOutOfBoundsException("");

注意:

1. throw 必须写在方法的内部
2. throw 后面new的异常对象, 必须是 "Exception" 或 "Excetion的子类" 的对象
3. 一个方法内部 throw 了一个异常对象, 则该方法可以分为2种情况来处理该异常:
  如果 throw 的是"运行时异常"(RuntimeException及其子类)对象, 那么可以不处理  该异常最终会交给JVM处理, 结果就是: 打印异常信息到控制台, 并立刻结束程序
  如果 throw 的是"编译时异常"(Exception及其子类), 则必须处理:

   
处理方式1: throws 抛出
   处理方式2: try...catch 捕获补充:
∆throws声明抛出异常
提前了解IO用到的一些异常类名:
FileNotFoundException: 文件找不到时抛出的异常, 一般是路径写错了引起
IOException: 只要是IO操作的异常都属于该异常, 是FileNotFoundException的父类
异常处理的第一种方式:

throws, 声明抛出 (方法自己不处理, 交给方法调用者处理, "甩锅给别人")、
作用: 告诉方法的调用者, 调用此方法有可能发生异常, 需要在编写代码时处理
格式:
修饰符 返回值类型 方法名() throws 异常类名1, 异常类名2, ... { }
try...catch:
捕获并处理异常 (方法内部自己处理异常, 不交给别人, "自己背锅")
格式:
    try {
        // 可能产生异常的代码
    } catch (异常类名 变量名) {
        // 处理异常的代码
        // 一般会将异常信息存储到日志中
    }
...
} catch (异常类名 变量名) {
        // 处理异常的代码
        // 一般会将异常信息存储到日志中
    }

注意:

1. try 中可能会抛出多种异常, 就可以写多个 catch 分别处理每种异常
2. 如果 try 中产生了异常, 就会从产生异常的那一行代码直接跳转到对应的 catch 中执行处理代码, 然后继续执行 try...catch 之后的其他代码; 如果 try 中没有产生异常, 那就不会执行 catch , 执行完 try 中的代码后, 继续执行 try...catch 之后的其他代码

∆Throwable中的三个异常处理方法
java.lang.Throwable
// 成员方法
String getMessage(): 异常的信息. 没有原因返回null
String toString(): 异常的类型和原因信息
void printStackTrace(): 使用标准错误输出流打印异常信息

格式:
    try {
        // 可能发生异常的代码
    } catch(异常类型 异常变量名) {
        // 处理异常
    }
...
catch(异常类型 异常变量名) {
        // 处理异常
    } finally {
        // 无论是否发生异常, 是否捕获, 最后都会执行的代码.
        // 通常在这里执行释放资源的操作
    }
注意:
1. finally 必须和 try...catch 一起使用
2. finally 一般用于释放资源 (IO流时用到)
捕获多个异常:
1. 多个异常分别 try...catch 处理
2. 一个 try 多个 catch
        如果异常存在继承关系, 子类异常在上, 父类异常在下
3. 多个异常, 一次捕获一次处理

  用Exception多态捕获
如果 finally 代码块中有 return 语句, 则永远返回 finally 中的 return 语句的值
应该避免在 finally 中写 return 语句

子父类继承关系下, 子类重写父类带有 throws 的方法:
1. 如果父类抛出多个异常, 子类重写父类方法时可以有3种方式:
  a: 抛出和父类相同的异常
  b: 抛出父类异常的子类
  c: 不抛出异常

2. 父类方法没有抛出异常, 子类重写父类该方法时也不可抛出异常
  此时子类产生该异常, 只能捕获处理, 不能声明抛出
  一般情况下:
    父类方法声明的异常是什么样的, 子类重写的方法声明异常就什么样, 保持一致即可

∆自定义异常
如果Java提供的异常类不足以满足我们的需求, 我们也可以自己定义异常类
定义编译时异常: 继承 Exception
定义运行时异常: 继承 RuntimeException
∆多线程
计算机基本概念:并发与并行
并发: (交替执行) 指两个或多个事件在"同一时间段内"发生
并行: (同时执行) 指两个或多个事件在"同一时刻"发生 (同时发生)
计算机基本概念:进程
进程: 一个应用程序在内存中的一次执行过程
每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程
进程也是程序的一次执行过程,是系统运行程序的基本单位
系统运行一个程序即是一个进程从创建、运行到消亡的过程

计算机基本概念:线程
线程: 是进程内的一个独立执行单元 (一条代码执行路径)
一个程序运行后至少有一个进程, 一个进程中可以包含多个线程
多线程的好处:
效率高
多个线程之间互不影响

∆线程的调度
调度: 多个线程要并发地执行, 哪个线程被执行, 哪个线程不被执行, 就是调度
线程的调度方式:   Java使用的是"抢占式"调度
1. 分时调度: 所有线程轮流使用CPU, 平分占用CPU的时间
2. 抢占式调度: 优先让优先级高的线程使用CPU; 如果优先级相同, 则随机选择一个线程执行

∆主线程:
我们以前编写的代码, 也在一条线程中执行, 该线程叫作"main线程", 也称为"主线程"
如果我们没有额外创建线程, 那么我们的程序就只有一个线程, 即主线程, 此时程序是"单线程"的
单线程的执行特点:
同一个线程内的代码, 从上往下依次执行

实现多线程的第一种方式:
1. 定义类, 继承 Thread 类
2. 重写 run() 方法, run方法内部是线程要执行的任务
3. 创建Thread子类的对象, 调用 start() 方法启动线程
java.lang.Thread类: 表示线程. 实现了Runnable接口
    void start(): 启动线程, 即让线程开始执行run()方法中的代码

注意:
必须调用 start() 方法来开启线程, 不能直接调用 run() 方法, 调用 run() 会变成单线程
同一个线程对象, 不能多次调用 start() 方法
Java是抢占式调度, 不同线程的代码, 执行顺序是随机的
l 多线程的结果的随机性打印结果。
抢占式,本质是多个线程在抢夺cpu的资源,
l 获取当前线程的名称
1. String get.name()
2. currentThread静态方法直接掉用,获取名称
l 设置线程名字:
1. set.Name
2. 创建一个带参数的构造方法,参数传递线程名称,
修改添加线程创建对象以后 对象名.setname
修改main线程的名字直接在main方法中Thread.setname
l Thread底下的sleep方法:
表示钟表内部的时间的,让它放慢1秒后执行
l 创建多线成的第二种方法Runnable
   创建多线程程序的第二种方式:实现Runnable接口
    java.lang.Runnable
        Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为 run 的无参数方法。
    java.lang.Thread类的构造方法
        
(1)Thread(Runnable target) 分配新的 Thread 对象。
        
(2)Thread(Runnable target, String name) 分配新的 Thread 对象。
   
实现步骤:

        1.创建一个Runnable接口的实现类
      
2.在实现类中重写Runnable接口的run方法,设置线程任务
      
3.创建一个Runnable接口的实现类对象
     
   4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
      
5.调用Thread类中的start方法,开启新的线程执行run方法

    Thread实现Runnable接口创建多线程程序的好处:
        1.避免了单继承的局限性
            一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类
            实现了Runnable接口,还可以继承其他的类,实现其他的接口
      
2.增强了程序的扩展性,降低了程序的耦合性(解耦)
耦合性: 相互之间的关系的紧密程度
耦合性高: 相互之间的关系非常紧密
耦合性低: 相互之间的关系不太紧密
我们追求 "低耦合"
            实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离(解耦)
            实现类中,重写了run方法:用来设置线程任务
            创建Thread类对象,调用start方法:用来开启新线程
匿名内部类创建接口
new 父接口/父类() {
    重写方法
};
继承Thread类
实现Runnable接口
l 线程安全的问题图解:模拟电影院卖票:线程安全问题
问题发生场景:
        多个线程操作共享资源
问题发生原因:
        JVM是抢占式调度, CPU在每个线程之间切换是随机的, 代码执行到什么位置是不确定的
        在操作共享资源时, 由于一个线程还没有执行完, 另一个线程就来操作, 就会出现问题
如何解决:
        在操作共享资源时, 让线程一个一个来执行, 不要并发操作共享变量, 就可以解决问题
l 解决线程安全的解决问题方式1:同步代码块
1. 同步技术三种
(1) 同步代码块
解决线程安全问题的一种方案:使用同步代码块
格式:

    synchronized(锁对象){
        可能会出现线程安全问题的代码(访问了共享数据的代码)
    }
注意:
   
1.通过代码块中的锁对象,可以使用任意的对象
   
2.但是必须保证多个线程使用的锁对象是同一个
   
3.锁对象作用:
把同步代码块锁住,只让一个线程在同步代码块中执行
同步代码块就类似于房间和房门
房间
+------+
|      |       线程1
|       \ 门锁  线程2
|      |       线程3
+------+
线程进入房间后, 锁上房间, 其他线程就进不来
+------+
|      |
| 线程1|   线程2
|      |   线程3
+------+
线程1做完事情, 打开锁出了门, 其他线程就可以抢着进来
+------+
|      |
|       \线程2
|      |       线程3
+------+
线程1
同步代码块图解
l 同步技术的原理
锁对象, 也称为"同步锁", "对象锁", "对象监视器"
l 同步的原理:
    线程进入同步代码块前, 会"争夺锁对象", "只有一个线程"会抢到锁对象
    进入同步代码块的线程, 会"持有锁对象", 并执行同步代码块中的代码
    此时同步代码块外的线程, 处于"阻塞"状态, 只能等待
    当同步代码块内的线程执行完代码块, 会离开同步代码块, 并"归还锁对象"给同步代码块
    等在同步代码块外的其他线程就可以继续争夺锁对象
l 解决线程安全问题的二种方案:使用同步方法
使用步骤:
   
1.把访问了共享数据的代码抽取出来,放到一个方法中
   
2.在方法上添加synchronized修饰符

格式:定义方法的格式
修饰符 synchronized 返回值类型 方法名(参数列表){    可能会出现线程安全问题的代码(访问了共享数据的代码)
非静态同步方法的锁对象: this
静态同步方法:
        public static synchronized void method(){
                // 可能会产生线程安全问题的代码
        }
静态同步方法的锁对象: 当前类的字节码对象 Class对象
RunnableImpl.class -> Class对象
l 获取一个类的字节码对象的3种方式:
        1. 对象名.getClass()          new RunnableImpl().getClass()
        2. 类名.class                 RunnableImpl.class
        3.Class.forName("类的全名");  Class.forName("com.itheima.test05.RunnableImpl");
l 字节码对象的特点:
        同一个类, 他的字节码对象只有"唯一的一个"
Person
        new Person()  this
    new Person()  this
    ..
Person.class 只有一个
锁对象必须是多个线程共享的同一个对象
}
l 第三种 方式
解决线程安全问题的三种方案:使用Lock锁
java.util.concurrent.locks.Lock接口
Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。
Lock接口中的方法:

    void lock()获取锁。
    void unlock()  释放锁。
java.util.concurrent.locks.ReentrantLock implements Lock接口
使用步骤:
    1.在成员位置创建一个ReentrantLock对象
    2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
    3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁

使用修改代码, 使用Lock锁解决卖票问题
public class RunnableImpl implements Runnable {
    // 定义多线程共享的票数
    private int ticket = 100;
    // 定义Lock锁
    Lock l = new ReentrantLock();
    @Override
    public void run() {
        // 这个run方法会被3个窗口执行, 所以每个窗口不知道循环多少次才能卖完, 所以使用死循环
        while (true) {
            // 加锁(获取锁)
            l.lock();
            try {
                // 判断, 当有票时, 再卖票
                if (ticket > 0) {
                    // 先打印当前窗口卖出的票
                    System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "张票");
                    // 然后让票数-1
                    ticket--;
                } else {// 在这里也可以写个else, 里面break
                    break;  // 没票了, 结束循环
                }
            } finally {
                // 释放锁
                l.unlock();
            }
        }
    }
}
public class Test {
    public static void main(String[] args) {
        // 先创建一个卖票任务
        RunnableImpl runnable = new RunnableImpl();
        // 创建3个线程模拟3个售票窗口
        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        Thread t3 = new Thread(runnable);
        // 为了看的明显, 也可以给线程设置名字
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        // 启动线程, 开始卖票
        t1.start();
        t2.start();
        t3.start();
    }
}
l 线程的状态
锁对象, 也称为"同步锁", "对象锁", "对象监视器"   
Object类中关于线程的方法:
java.lang.Object类:
        // 成员方法 (<<注意>>: 只能通过"锁对象"调用)
        void notify(): 随机唤醒在同一个锁对象上的某一个处于等待状态的线程
        void notifyAll(): 唤醒所有在同一个锁对象上处于等待状态的线程
        void wait(): 让当前线程处于"无限等待"状态
        void wait(long timeout): 让当前线程处于"计时等待"状态, 时间到或被唤醒后结束此状态
        void wait(long timeout, int nanos): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态
        "注意!! 以上方法只能通过锁对象调用"
l 线程的生命周期中, 可以出现有6种状态:
    1. "NEW 新建"
       线程被创建, 但没有调用 start() 启动
    2. "RUNNABLE 可运行"
       调用 start()方法后已启动, 但可能正在执行 run() 方法的代码, 也可能正在等待CPU的调度
    3. "BLOCKED (锁)阻塞"
       线程试图获取锁, 但此时锁被其他线程持有
    4. "WAITING 无限等待"
       通过锁对象调用无参的 wait() 进入此状态.
       等待其他线程通过锁对象执行 notify() 或 notifyAll() 才能结束这个状态
    5. "TIMED_WAITING 计时等待"
       如通过锁对象调用有参的 wait(long millis) 或 sleep(long millis), 则进入此状态.
       直到时间结束之前被其他线程通过锁对象执行 notify()或 notifyAll()唤醒, 或时间结束自动唤醒
    6. "TERMINATED 终止"
       run()方法结束(执行结束, 或内部出现异常), 则进入此状态
线程间通信
卖包子吃包子
*/
public class Test {
    public static void main(String[] args) {
        // 创建一个对象作为锁对象
        Object lock = new Object();
        // 使用匿名内部类方式创建一个线程, 作为顾客线程
        new Thread(){
            @Override
            public void run() {
                // 死循环要包子吃包子
                while (true) {
                    // 使用同步代码块, 同步代码块中有锁对象, 可以用来调用wait()方法
                    synchronized (lock) {
                        // 先向老板要包子
                        System.out.println("[顾客说:] 老板! 来2斤包子!");
                        // 顾客先等着老板做
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // 如果能执行到这里, 说明被老板唤醒了, 开始吃
                        System.out.println("[顾客说:] 嗯嗯!真香~");
                        System.out.println("-------------------");
                    }
                }
            }
        }.start();
        // 使用匿名内部类方式创建一个线程, 作为老板线程
        new Thread(){
            @Override
            public void run() {
                // 死循环做包子
                while (true) {
                    // 先睡5秒模拟做包子的时间(实际上是为了让老板线程抢锁不要太快)
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 使用同步代码块, 同步代码块中有锁对象, 可以用来调用notify()方法
                    synchronized (lock) {
                        // 打印做好了包子
                        System.out.println("[老板说:] 包子做好了, 来吃吧");
                        // 老板要通知顾客, 使用锁对象调用notify()
lock.notify();
} }}     }.start();
}}
l Object类中wait(long timeout)和notifyAll()方法
// 成员方法 (只能通过"锁对象"调用)
        void notifyAll(): 唤醒所有在同一个锁对象上处于等待状态的线程
        void wait(long timeout): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态
l wait() 和 sleep() 的区别:
        1. wait会释放锁, 恢复时需要重新获取锁; sleep不会释放锁
        2. wait可以被notify/notifyAll唤醒; sleep不会
        3. wait要用锁对象调用; sleep要用Thread类名调用
l 进入到TimeWaiting(计时等待)有两种方式
1.使用sleep(long m)方法,在毫秒值结束之后,线程睡醒进入到Runnable/Blocked状态
2.使用wait(long m)方法,wait方法如果在毫秒值结束之后,还没有被notify唤醒,就会自动醒来,线程睡醒进入到Runnable/Blocked状态
唤醒的方法:
     void notify() 唤醒在此对象监视器上等待的单个线程。
     void notifyAll() 唤醒在此对象监视器上等待的所有线程。
java.lang.Thread类: 表示线程. 实现了Runnable接口
        // 构造方法
    Thread(): 创建Thead对象
    Thread(String threadName): 创建Thead对象并指定线程名
    Thread(Runnable target): 通过Runnable对象创建Thread对象
    Thread(Runnable target, String threadName): 通过Runnable对象创建对象并指定线名
        // 成员方法
    void run(): 用于让子类重写, 表示该线程要执行的任务.不能直接调用
    void start(): 启动线程, 即让线程开始执行run()方法中的代码
    String getName(): 获取线程的名称
    void setName(String name): 设置线程名称
        // 静态方法   
    static Thread currentThread(): 返回对当前正在执行的线程对象的引用
    static void sleep(long millis): 让所在线程睡眠指定的毫秒
u 今日API
Thread Thread(): 创建Thead对象
    Thread Thread(String threadName): 创建Thead对象并指定线程名
    Thread Thread(Runnable target): 通过Runnable对象创建Thread对象
    Thread Thread(Runnable target, String threadName): 通过Runnable对象创建对象并指定线程名
        // 成员方法
    void run(): 用于让子类重写, 表示该线程要执行的任务.不能直接调用
    void start(): 启动线程, 即让线程开始执行run()方法中的代码
    String getName(): 获取线程的名称
    void setName(String name): 设置线程名称
        // 静态方法
    static Thread currentThread(): 返回对当前正在执行的线程对象的引用
    static void sleep(long millis): 让所在线程睡眠指定的毫秒

java.lang.Object类:
        // 成员方法 (只能通过"锁对象"调用)
        void notify(): 随机唤醒在同一个锁对象上的某一个处于等待状态的线程
        void notifyAll(): 唤醒所有在同一个锁对象上处于等待状态的线程
        void wait(): 让当前线程处于无限等待状态
        void wait(long timeout): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态
        void wait(long timeout, int nanos): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态


0 个回复

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