《Java编程思想》并发篇:

《Java编程思想》并发篇:

  • 单核CPU某个时间点只能执行一个线程

  • Thread类实现了Runnable接口

    • Runnable接口中就一个run方法
  • Thread类的线程对象调用start方法来启动一个线程

    • start方法底层还调用了run方法
    • 这其实是JVM底层与OS的交互,启动了一个线程
  • 执行线程代码的方法:

    1. 写一个继承Thread类的子类,去重写run方法,再去创建这个子类的对象,调start方法

    2. 写一个类实现Runnable接口,去重写run方法,再去创建这个类的对象,把引用当作参数放入new Thread(),调start方法、

    3. 线程池

        ExecutorService exec = Executors.newCachedThreadPool();//这种线程池是需要好多线程就创建好多线程
        ExecutorService exec = Executors.newFixedThreadPool(线程数量);//预先指定线程数量
        ExecutorService exec = Executors.newSingleThreadExxcutor();//就是FixedThreadPool创建一个线程
        exec.execute(new LifeOff());
      
  • 第二种方法比第一种更加灵活,平时使用线程池

  • Runnable是执行工作的独立任务,但它不返回任何值;如果需要任务完成时返回一个值,那么可以实现Callable接口而不是Runnable接口,实现它的call()方法,且必须使用ExecutorService.submit()方法调用它

  • yield()让步方法:让当前线程让出CPU的执行权,再由所有线程来公平竞争获取执行权

  • TimeUnit.SECONDS.sleep(休眠时间);使该线程进入睡眠状态

  • 后台线程(守护线程)且必须在线程启动之前调用setDaemon(true)方法

  • join()方法:调用join()可以控制线程的执行顺序

  • 共享资源:

    • 内置锁synchornized:

      • java提供synchornized关键字为防止资源冲突提供了内置支持

      • 当任务要执行的被synchornized保护的代码片段时,它将检查锁是否可以,执行代码,释放锁

      • 所有对象都自动含有单一的锁(也称监视器

      • 对于某个特定对象来说,其所有方法共享同一把锁

      • synchornized (含锁的对象) {执行的代码块}
        
      • synchornized对实例方法修饰,其实就是加上this锁

      • synchornized对静态方法修饰,其实就是加上Class锁

    • 外置锁Locks:

      • 与synchornized相比,不优雅,更灵活
      • 用synchornized关键字不能尝试着获取锁且最终获取锁会失败,或者尝试着获取锁一段时间,然后放弃它,要实现这些,必须实现concurrent库
  • 原子性:

    • 操作的原子性(不可切分
    • 原子性可以应用于除long和double之外的所有基本类型简单操作
      • 简单操作:简单的赋值和返回操作
    • 但是使用volatile关键字修饰long和double时,就获得所谓的简单操作的原子性
      • volatile关键字还确保了应用的可见性
        • 可见性:就是对一个域进行写操作,那么所有的读操作就可以看到这个修改,读的时候就不会读成之前没改的时候的值,因为有些时候改了,存在缓存中,还没更新到内存
        • 也就是说,volatile域会立即被写入到主存中,而读取操作就发生在主存中
    • 如果多个任务在同时访问某个域,那这个域就应该是volatile的,否则只能同步来访问
    • 同步操作也会导致向主存中刷新,导致可见
    • 一个任务所作的任何读写操作对于这个任务来说都是可见的,因此如果它只需要在这个任务中内部可视,那就不需设置volatile
      • 第一选择都是使用synchornized关键字,这是最安全的方式,尝试其他方式都是有风险的

线程本地存储:

  • 防止任务在共享资源上产生冲突的第二种方式是根除对变量的共享
  • 创建和管理线程本地存储可以由ThreadLocal类来实现

线程状态:

  • 一个线程可能是以下四种状态:
    1. 新建(new):刚创建时,短暂处于这个状态,此时它被分配了必需的系统资源,执行了初始化
    2. 就绪(Runnable):只要调度器把时间片分配给线程就可以运行
    3. 阻塞(Blocked): 某个条件阻止它的运行
      • 可能如下原因:
        1. sleep()
        2. wait()
        3. 在等待某个输入/输出
        4. 等待锁的释放
    4. 死亡(Dead):run()完就结束
  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值