zoukankan      html  css  js  c++  java
  • Java并发(1)

    线程和进程的区别

    每个进程拥有自己的一整套变量,而线程共享变量。

    在有些操作系统中,线程更轻量级,创建,撤销一个线程比启动新进程的开销要小得多

    启动线程

    应该讲要运行的任务与运行机制解耦

    Runnable r = new Runnable() {
        @Override
        public void run() {
        }
    };
    final Thread t = new Thread(r);
    t.start();

    interrupt方法请求终止线程

    interrupt()方法用来请求终止线程,调用interrupt()时,中断状态(boolean类型)将被置位,每个线程应该不时检查这个状态。

    while (!Thread.currentThread().isInterrupted()) {
        //do more work
    }

    如果线程被阻塞,调用interrupt()会抛出InterruptedException异常。如果已经调用了interrupt(),线程调用sleep()会清除中断状态位并抛出InterruptedException异常。

    线程状态

    new,用new操作符新建一个线程,线程还没开始运行,处于new状态

    runnable,调用start(),线程处于runnable状态。可能正在运行,也可能没有运行,取决于操作系统给线程提供运行时间。

    blocked,一个线程试图获取一个内部的对象锁,该锁被其他线程所持有,该线程进入阻塞状态。

    waiting,线程等待另一个线程通知调度器一个条件时,进入等待状态。如调用Object.wait(),Condition.await()等

    timed waiting,加超时参数,进入timed waiting状态,这一状态保持到超时期满或接受到适当的通知。

    terminated,线程终止。终止的两种情况:run()正常退出自然死亡。因一个未捕获异常而意外死亡。

    线程优先级

    每个线程都有优先级,setPriority()设置,范围为1到10,默认为5。

    每当线程调度器选择新线程时,会选择有较高优先级的线程。当虚拟机依赖于宿主机的线程实现机制时,Java线程优先级被映射到宿主机的线程优先级上,优先级个数也许更多,也许更少。

    守护线程

    Thread.setDaemon(true)将线程转为守护线程。守护线程的唯一用途是为其他线程提供服务,当只剩下守护线程时,虚拟机退出。

    守护线程随时会发生中断。

    竞争条件(race condition)

    两个线程同时去更新一个对象,更新的过程不是原子操作,导致数据出现了讹误。

    锁的种类

    对象的内部锁。使用关键字synchronized,修饰方法,代码块,使用对象的内部锁,改锁只有一个条件。

    ReentrantLock。java.util.concurrent包下的类。

    ReentrantLock和条件对象

    代码基本结构如下:

    lock.lock();
    try {
        //do something
    } finally {
        lock.unlock();
    }

    ReentrantLock是可重入的,线程可以重复获得已持有的锁,锁保持一个持有计数(hold count)跟踪lock()和unlock()的嵌套调用。

    条件对象,来管理那些已经获得了一个锁但是却不能做有效工作的线程。一个锁对象可以有一个或多个条件对象,通过newCondition()获得。

    Condition myCondition = lock.newCondition();
    myCondition.await();

    await()使得线程进入waiting状态,并放弃了锁,调用await()的线程进入该条件对象的等待集。当锁可用时,线程不能马上解除阻塞,直到另一个线程调用同一个条件对象的signal(),signalAll()才行能。

    signal(),signalAll()不会立即激活一个线程,仅仅是解除等待线程的阻塞,以便这些线程可以在当前线程退出同步方法后,通过竞争实现对对象的访问。

    锁和条件

    锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码片段

    锁可以管理试图进入被保护代码段的线程

    锁可以有一个或多个条件对象

    条件对象管理那些已经进入被保护的代码段却不能执行的线程

    volatile关键字

    volatile关键字为实例域的同步访问提供一个免锁机制,那么编译器和虚拟机知道该字段可能被另一个线程并发更新。

    final关键字

    final保证其他线程在构造函数完成构造之后才能看到这个变量,而不是null。

    导致死锁的情况

    线程局部变量

    ThreadLocal为各个线程提供各自的实例

    final ThreadLocal<SimpleDateFormat> threadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat());
    threadLocal.get().format(new Date());
  • 相关阅读:
    VueCLI3如何更改安装时的包管理器
    查天气43课-46课
    【Python第31课到42课】
    【Python第16课到30课 】
    Python笔记
    【AC】九度OJ题目1153:括号匹配问题
    【AC】九度OJ题目1436:Repair the Wall
    【WA】九度OJ题目1435:迷瘴
    Matlab图片改颜色通道不改名存储
    [Linux 操作] awk操作の 打印图片路径
  • 原文地址:https://www.cnblogs.com/minguo/p/12393074.html
Copyright © 2011-2022 走看看