java进程与线程的一些知识(未完待续...)

进程与线程

  • 问题:操作系统.CPU.核心联系和区别 (CPU 即核心数的总称.核心数代表处理事务的并行数.)
  •  
  • 线程的并发和并行
    • 二者的区别
      • 1.并发指单位时间内 CPU 可以调度的线程数量,即单位时间内可交替执行的线程数
      • 2.并行指同一时间内可同时运行的线程数,即并行数的线程是同时执行的
    • 高并发的好处
      • 1.可以使 CPU 资源利用最大化
      • 2.用户操作的响应速度加快
      • 3.可以使代码模块化,异步化,简单化.比如:主线程代码和各子线程代码可以放在不同模块中,提高可读性和复用性
  • 区别
    • 进程是操作系统分配资源和调度的最小单位.包括 CPU,内存和磁盘
    • 进程间是相互独立的
    • 线程是 CPU调度的最小单位,线程必须依赖于进程存在,
    • 线程没有系统资源.只有保证任务运行的少量资源如栈,寄存器.属于相同进程的所有线程共享该进程分配到的资源
  • java线程的创建方式
    • 由 Thread 类派生子类,覆写 run()方法写入任务代码
    • 实现 Runnable 接口,并实现 run()方法写入任务代码..实例化 Thread 类,并在构造方法中传入 Runnable 实现类的实例
    • 实现 Callable 接口,并实现call()方法写入任务代码
      • 使用方式:
        • 实例化 Thread 类,并在构造方法传入 FutureTask 实例化 对象.FutureTask 实例化对象时传入 Callable 实现类的实例
        • 涉及到 Future 接口和 FutureTask 类
          • Future泛型接口 提供 cancel(),get(),isCancle(),isDone()方法.其中 get()方法返回泛型对象
          • FutureTask 类实现接口为 Runnable和 Future 接口.构造方法传入 Callable 接口实现类,因此 FutureTask get()方法可获取线程返回值
      • 说明
        • Callable 接口中的 call()方法是带有返回值的,也就是说用该类方式创建的线程可以将任务代码的结果返回给线程创建者
        • 开启线程者在调用 futureTask.get()方法获取线程返回值时.在拿到返回结果之前开启者线程会处于阻塞状态
  • Thread 中的方法
    • suspend()暂停线程;resume()重新开始线程;stop()停止线程;这三个方法在 jdk 中是不建议开发者调用的,因为在调用者三个方法之后.线程并不一定会释放持有资源
    • start()方法:Thread 对象只有调用此方法后,创建的线程才处于就绪状态.即可以随时被 cpu 调度执行的状态.值得注意的是 run()方法只是一个普通的方法.代表线程需执行任务的方法.调用此方法并不会使线程开启
    • interrupt();isInterrupted();interrupted(): interrputed()为中断线程的方法.该方法只是给线程的中断标志置为 true,线程是否中断需要看线程任务中的具体处理;isInterrupted()方法为获取中断标志位的方法.Thread 可根据该方法返回值进行业务代码是否执行下去进行判断;interrupted()方法为静态方法.该方法也会返回线程是否被中断的标志位.不同于 isInterrupted()方法的是.调用该方法之后,中断标志位会重新被置为 false
    • join():在A线程中调用B线程的 join 方法时,A线程会处于等待状态直到 B 线程执行结束,A 线程才会继续执行,不会释放锁
    • yield():调用该方法的线程会立刻释放资源挂起线程.调用 yield()的线程虽然会立刻让出资源.但释放的同时也会去争取资源.因此挂起之后是有可能再一次被立即执行的,方法被调用是线程不会释持有放锁
    • wait():使线程处于阻塞状态,接收到同一对象的 notify()/notifyAll()方法时线程可继续执行 wait()之后的代码.调用对象需要与 调用notify()/notifyAll()方法的对象一致,线程处于等待状态之后会自动释放持有的对象锁
    • notfy()/notifyAll():使因为调用对象的 wait()方法处于阻塞状态的线程重新处于就绪状态,继续执行.调用对象需要与 调用wait()方法的对象一致.由于 notify()只能通知到一个处于等待状态的线程并且无法指定被通知线程.所以一般建议使用 notifyAll()方法进行广播通知.会自动释放持有的对象锁
    • sleep():使线程处于阻塞状态一段时间.阻塞期间线程不会释放持有的对象锁
  • 线程同步机制
    • ThreadLocal
      • ThreadLocal 为线程内变量,只能在线程内被访问,ThreadLocal 会作为变量的副本附属在创建的各个线程中,以保证各个线程访问该变量值的时候不被彼此影响,可以隔离不同线程之间对同一变量的访问
      • 包含方法
        • initalValue(),覆写该方法可以初始化变量值
        • get():线程可获取变量值
        • set():线程可通过该方法将变量设置为其他值
        • remove():线程可去除附属于自己的变量值
    • 内置锁:synchronized
      • 类锁/对象锁
        • 类锁为 synchronized修饰静态方法或是synchronized ()内传入的对象为静态对象
        • 对象锁为synchronized 修饰普通成员方法或是 synchronized()内传入非空类成员变量
      • 特点
        • 内置锁在等待获取对象锁过程中不能被中断,即 AB 线程需要同一把锁,B 需要等 A 释放锁之后才可进行.当 A 被阻塞的时候,B 会一直处于等待状态
        • 内置锁不能判断是否获取到对象锁的状态
        • 内置锁可自动释放锁
      • 注意事项
        • 类锁锁住的对象为包含静态方法的类或是静态变量所属类的 Class 对象.该对象在虚拟机内有且只有一个
        • 不同对象的对象锁相互独立
        • 类锁和对象锁实际意义上锁住的都是对象.类锁锁住的是 Class 对象.对象锁锁住的为实例对象
        • 内置锁为可重入锁,即加锁方法递归时可以重复获取同一把锁
    • 显式锁Lock:
      • Lock 接口:
        • 实现类:可重入锁ReentrantLock
        • 实现类:读写锁
      • 特点
        • Lock可以使用 isLocked()判断线程获取锁的状态
        • Lock 不会自动释放锁.因此在加锁后需要在 finally{}代码块中调用 unlock()方法来释放锁
        • 使用 Lock 加锁时,使用 tryLock()方法来尝试获取锁,如果获取锁失败可以结束线程
    • 可重入锁
      • 可重入锁即为在同一方法中可重复被获取的锁的机制
      • 可重入锁按次序计数被重复获取锁的次数.在释放锁时一次释放
      • 可重入锁机制是为了防止带有锁的方法递归时造成死锁现象
      • jdk 内置锁 为可重入锁
    • 公平锁/非公平锁
      • 公平锁即为多个线程需要持有相同对象的锁时,按照启动顺序依次获取该对象锁
      • 非公平锁即为多个线程需要持有相同对象的锁时.当某个线程释放锁后,如果有刚启动的线程则直接获得锁.等待的锁继续等待
      • 由于线程挂起和启动时切换上下文是需要消耗时间的.所以公平锁的执行效率普遍低于非公平锁
      • 内置锁为非公平锁.ReentrantLock 可以设置为公平/不公平锁,默认为非公平锁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值