zoukankan      html  css  js  c++  java
  • java-线程

    一、状态

    java线程存在以下几种状态:

    1: 创建状态(New):线程被new出来,还未调用start

    2: 就绪状态(Runnable):又称为可执行状态,调用线程的start方法后,线程处于就绪状态,,线程调度程序还未给该线程分配cpu时间片执行。

    3: 运行状态(Running):线程调度程序分配cpu时间片来执行线程代码。

    4: 阻塞状态(Blocked):线程在运行过程中由于某种原因暂停运行进入阻塞状态,只有满足条件后进入就绪状态,获取cpu后才能再次进入运行状态。

    阻塞的情况分三种:

    A:等待阻塞(wait):调用wait()方法,与synchroined一起使用,线程进入对象等待池,释放synchroined的锁,处于阻塞状态。当有其他线程notify,notifyAll后线

                                  进入锁标识等待池,即进入同步阻塞状态。

    B:同步阻塞:线程运行过程中需要获取锁,但该锁被其他线程持有,则该线程进入锁标识等待池,处于同步阻塞状态。当线程获取锁之后,线程进入就绪状态。

    C:其他阻塞:当线程sleep,或者join,或者发出I/O请求后,知道yield时间到,sleep时间到,join的线程执行完,或者I/O返回后,线程进入就绪状态。

    5: 死亡状态(Dead):当线程Run方法退出或者运行出现异常线程停止时,线程就会消亡。

    二、synchronized的用法

    synchronized有两种用法:

    一种是写在方法前,如果该方法是静态方法,则获取的锁是类锁,多线程调用该类中所有的实例的该方法都是互斥的。如果该方法不是静态的,则获取的锁是对象锁,多线程调用同一个实例的该方法是互斥的,调用不同实例则不是互斥的。

    一种是同步代码块:synchronized(){//....},同样根据方法是否是静态方法区分获取对象锁还是类锁。

    三、java线程的sleep(),wait(),notify(),yield();

    1.sleep()使线程休眠一段时间,一段时间结束后,线程进入可执行状态,但并不是立即执行,只是在被排程器调用的时候才执行。在休眠期间,并不释放所持有的“锁”,sleep能够让低优先级的线程有机会运行。

    2 . yield( ): 暂停线程的执行,给其它具有相同优先权的线程执行的机会,若此时没有其它线程执行,则此线程继续执行。这个函数并不会释放锁住的对。(线程进入就绪状态,不会释放锁,让同优先级的其他线程有机会运行。但下次可能继续分配cpu时间片,进入运行状态。)

    3.  join( ): 等待加入的线程执行完毕才会执行下一个线程。加入的线程通过interrupt( )来唤醒。(让一个线程B加入到一个线程A的尾部,在A运行完前,B不能运行。)

    4.  wait( ): 类似sleep( ), 不同的是,wait( )会先释放锁住的对象,然后再执行等待的动作。另外,由于wait( )所等待的对象必须先锁住,因此,它与synchronized一起使用,即必须想获取指定的锁lock,才能lock.wait。wait时,会释放lock,线程进入对象等待池,释放synchroined的锁,处于阻塞状态。当有其他线程notify,notifyAll后线 进入锁标识等待池,即进入同步阻塞状态。注意,这个函数属于Object类。

    5.notify:与synchronized一起使用,即必须想获取指定的锁lock,才能lock.notify,synchronized代码块结束后释放锁,通知一个因lock而进入等待阻塞的线程进入同步阻塞状态。

    6.notifyAll:与synchronized一起使用,即必须想获取指定的锁lock,才能lock.notifyAll,synchronized代码块结束后释放锁,会通知所有因Lock而进入等待阻塞的线程进入同步阻塞状态。

    补:

    JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法。

    ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用

    ②wait() 与  notify/notifyAll() 的执行过程

    ③中断 调用wait()方法进入等待队列的 线程

    ④notify 通知的顺序不能错

    ⑤多线程中测试某个条件的变化用 if 还是用 while?

    ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用

    wait() 与 notify/notifyAll() 是Object类的方法,在执行两个方法时,要先获得锁。那么怎么获得锁呢?

    在这篇:JAVA多线程之Synchronized关键字--对象锁的特点文章中介绍了使用synchronized关键字获得锁。因此,wait() 与  notify/notifyAll() 经常与synchronized搭配使用,即在synchronized修饰的同步代码块或方法里面调用wait() 与  notify/notifyAll()方法。

    ②wait() 与  notify/notifyAll() 的执行过程

    由于 wait() 与  notify/notifyAll() 是放在同步代码块中的,因此线程在执行它们时,肯定是进入了临界区中的,即该线程肯定是获得了锁的。

    当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。

     当执行notify/notifyAll方法时,会唤醒一个处于等待该 对象锁 的线程,然后继续往下执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁。

    从这里可以看出,notify/notifyAll()执行后,并不立即释放锁,而是要等到执行完临界区中代码后,再释放。故,在实际编程中,我们应该尽量在线程调用notify/notifyAll()后,立即退出临界区。即不要在notify/notifyAll()后面再写一些耗时的代码。

  • 相关阅读:
    企业应用架构模式web表现层
    企业应用架构模式组织领域逻辑
    企业应用架构模式并发
    数据访问层
    企业应用架构模式映射到关系数据库
    企业应用架构模式引言
    领域驱动设计(精简版)
    企业应用架构模式分层
    服务层
    企业应用架构模式前言
  • 原文地址:https://www.cnblogs.com/lizhen-home/p/7376280.html
Copyright © 2011-2022 走看看