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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© dyynrahbsqt 中级黑马   /  2018-11-20 15:54  /  689 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

day06  线程 同步
线程多线程原理1: 线程执行的随机性
CPU执行哪个线程是随机, 不能人为干预
Java线程调度是抢占式, 多个线程互相抢夺CPU的执行权
补充:
第一种方式: 继承Thread类
        定义类继承Thread
        重写run()方法, 要执行的任务
        创建子类的对象, 调用start()方法启动线程
多线程原理2: 多线程的内存
多线程情况下, 每个线程都有各自的栈内存
每个线程各自的方法调用, 进的是各自线程的栈
栈是每个线程各自的, 堆是所有线程共用的
Thread常用方法: getName(), currentThread()
java.lang.Thread类: 表示线程. 实现了Runnable接口
hread常用方法: setName(), Thread(String name)
java.lang.Thread类: 表示线程. 实现了Runnable接口
        // 构造方法
    Thread(String threadName): 创建Thead对象并指定线程名
    // 成员方法
    void setName(String name): 设置线程名称
Thread常用方法: sleep()
java.lang.Thread类: 表示线程. 实现了Runnable接口
        // 静态方法
    static void sleep(long millis): 让所在线程睡眠指定的"毫秒"
创建多线程程序的方式2: 实现Runnable接口
创建线程的第2种方式:
        1. 定义类, 实现Runnable接口
        2. 重写 run() 方法
        3. 创建Runnable实现类对象
        4. 创建Thread类对象, 在构造方法中传入Runnable实现类对象
        5. 通过Thread对象调用start()方法启动线程
java.lang.Thread类: 表示线程. 实现了Runnable接口
        // 构造方法
    Thread Thread(Runnable target): 通过Runnable对象创建Thread对象
    Thread Thread(Runnable target, String threadName): 通过Runnable对象创建对象并指定线程名
Thread和Runnable的区别
实现Runnable的好处:   1. 避免单继承的局限性        
2. 增强了程序的扩展性, 降低了程序的耦合性(解耦)               
3. 线程是Thread, 任务是Runnable实现类对象. 相当于将线程和任务分离
匿名内部类方式创建线程
public class Test {
    public static void main(String[] args) {
        // 匿名内部类方式
        new Thread(new Runnable(){
            @Override
            public void run() {
                // 要执行的任务
            }
        }).start();
    }
}
解决线程安全问题方式1: 同步代码块
解决多线程操作共享数据的安全问题的3种方式:
        1. 同步代码块
        2. 同步方法
        3. 锁机制
同步代码块: 使用 synchronized 关键字修饰的代码块, 并传入一个当作锁的对象
格式:
    synchronized (锁对象) {
                // 操作共享数据的代码

    }

注意:
        锁对象可以是任意类型的一个对象
        锁对象必须是被多个线程共享的唯一对象
        锁对象的作用: 只让一个线程在同步代码块中执行
同步技术解决线程安全问题的原理
锁对象, 也称为"同步锁", "对象监视器"

同步的原理:
    线程进入同步代码块前, 会争夺锁对象, 只有一个线程会抢到锁对象
    进入同步代码块的线程, 会持有锁对象, 并执行同步代码块中的代码
    此时同步代码块外的线程, 处于阻塞状态, 只能等待
    当同步代码块内的线程执行完代码块, 会离开同步代码块, 并归还锁对象给同步代码块
    等在同步代码块外的其他线程就可以继续争夺锁对象
解决线程安全问题方式2: 同步方法
同步方法: 使用 synchronized 关键字修饰的方法, 具有默认的锁对象
非静态同步方法的锁对象: this
        // 非静态同步方法
        public synchronized void method(){
                // 可能会产生线程安全问题的代码
        }
静态同步方法:
        public static synchronized void method(){
                // 可能会产生线程安全问题的代码
        }
静态同步方法的锁对象: 当前类的字节码对象
获取一个类的字节码对象3种方式:
        1. 对象.getClass()
        2. 类名.class
        3. Class.forName("类的全路径");
线程安全和效率的特点:     线程安全, 效率低线程不安全, 效率高
线程的生命周期中, 可以出现有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()方法结束(执行结束, 或内部出现异常), 则进入此状态
Object类中wait(long timeout)和notifyAll()方法
java.lang.Object类:
        // 成员方法 (只能通过"锁对象"调用)
        void notifyAll(): 唤醒所有在同一个锁对象上处于等待状态的线程
        void wait(long timeout): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态

   
        

0 个回复

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