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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小北京 初级黑马   /  2018-11-20 15:25  /  513 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

线程:
多线程的原理:  1: 线程执行的随机性    CPU执行哪个线程是随机的,不能人为干预,  Java线程调度室抢占式的,多个线程互相抢夺
                              CPU的高速随机切换(本质)
                          多个线程抢占CPU资源
创建线程的 一种方式:
extends  Thread 继承
定义类继承Thread
重写run方法,写要执行的任务
创建子类的对象,调用.start( ) 方法开启线程.


多线程的原理:  2:多线程的内存   每个线程都有各自的栈内存
栈是每个线程各自的,  堆是每个线程共用的




/*Thread常用方法:
  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): 让所在线程睡眠指定的毫秒*/


   
  创建多线程程序的第二种方式: 实现Runnable接口
建线程的第2种方式:
        1. 定义类, 实现Runnable接口
        2. 重写 run() 方法, 要执行的代码(任务)
        3. 创建Runnable实现类对象 (任务对象)
        4. 创建Thread类对象, 在构造方法中传入Runnable实现类对象 (将任务和线程绑定)
        5. 通过Thread对象调用 start() 方法启动线程


Thread和Runnable的区别:
       1. 多个相同的程序代码的线程去共享同一个资源。
2. 可以避免java中的单继承的局限性。
3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和数据独立。


匿名内部类创建线程:
new 父接口/父类() {
    重写方法
};


继承Thread类
实现Runnable接口


线程的安全问题:
JVM是抢占式调度, CPU在每个线程之间切换是随机的, 代码执行到什么位置是不确定的
        在操作共享资源时, 由于一个线程还没有执行完, 另一个线程就来操作, 就会出现问题
如何解决:
        在操作共享资源时, 让线程一个一个来执行, 不要并发操作共享变量, 就可以解决问题

解决线程安全问题方式:
                1. 同步代码块
                2. 同步方法
                3. Lock锁机制
同步代码块: 使用 synchronized 关键字修饰的代码块, 并传入一个当作锁的对象
格式:
    synchronized (锁对象) {
                // 操作共享数据的代码
注意:
        锁对象可以是"任意类型的一个对象"
        锁对象必须是"被多个线程共享的唯一的"对象
        锁对象的作用: 只让一个线程在同步代码块中执行
            }


同步技术解决线程安全问题的原理:锁对象, 也称为"同步锁", "对象锁", "对象监视器"


解决线程安全问题方式2: 同步方法
同步方法: 使用 synchronized 关键字修饰的方法, 具有默认的锁对象


非静态同步方法的锁对象: this
   
            非静态同步方法
        public synchronized void method(){
                可能会产生线程安全问题的代码
        }


静态同步方法
        public static synchronized void method(){
                // 可能会产生线程安全问题的代码
        }


获取一个类的字节码对象的3种方式:
        1. 对象名.getClass()          new RunnableImpl().getClass()
        2. 类名.class                 RunnableImpl.class
        3. Class.forName("类的全名");  Class.forName("com.itheima.test05.RunnableImpl");


字节码对象的特点:
        同一个类, 他的字节码对象只有"唯一的一个"


Person
        new Person()  this
    new Person()  this
    ...
Person.class 只有一个
   
锁对象必须是多个线程共享的同一个对象


解决线程安全问题方式3: Lock锁
     void lock(): 获取锁
        void unlock(): 释放锁


线程间的通信:
线程的生命周期中, 有哪6种状态
锁对象, 也称为"同步锁", "对象锁", "对象监视器"
// 成员方法 (<<注意>>: 只能通过"锁对象"调用)
        void notify(): 随机唤醒在同一个锁对象上的某一个处于等待状态的线程
        void notifyAll(): 唤醒所有在同一个锁对象上处于等待状态的线程
        void wait(): 让当前线程处于"无限等待"状态
        void wait(long timeout): 让当前线程处于"计时等待"状态, 时间到或被唤醒后结束此状态
        void wait(long timeout, int nanos): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态
        "注意!! 以上方法只能通过锁对象调用"

Object类中wait(long timeout)和notifyAll()方法:
wait() 计时等待, 何时可以唤醒        (让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态)
notifyAll() 会唤醒什么样的线程     唤醒所有在同一个锁对象上处于等待状态的线程


wait() 和 sleep() 的区别:
        1. wait会释放锁, 恢复时需要重新获取锁; sleep不会释放锁
        2. wait可以被notify/notifyAll唤醒; sleep不会
        3. wait要用锁对象调用; sleep要用Thread类名调用

0 个回复

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