常见方法
sleep()
- sleep让当前正在执行的线程暂停,进入阻塞态,时间结束进入就绪态
- 让出cpu时不理会其他线程的优先级
- sleep的方法声明抛出了interruptedExceptiin,调用者必须处理,捕获或抛出
- 不释放同步监视器
yield()
- yield让当前正在执行的线程暂停,立马进入就绪态,因此没有时间参数。
- yield在让出cpu时只会给同优先级或更好优先级
- 方法声明没有抛出异常
- 不释放同步监视器
suspend()
线程通信常用方法
下面是使用synchronized关键字来保证线程同步的方法
wait()
- 必须通过同步监视器来调用这个方法(同步代码块是括号里的对象,同步方法是调用者)
- 导致当前线程等待暂停,进入阻塞态,直到有其他人来唤醒它(调用该同步监视器的notify()方法或者notifyAll()方法即可唤醒它),唤醒后它才进入就绪态
- wait()会让当前线程释放对该同步监视器的锁定
notify()notifyAll()
- 必须通过同步监视器来调用这个方法(同步代码块是括号里的对象,同步方法是调用者)
- notify()唤醒在此同步监视器上等待的单个线程(只有当前线程放弃对该同步监视器的锁定后(使用wait()会放弃)执行被此方法唤醒的线程)
- notifyAll()唤醒在此同步监视器上等待的所有线程只有当前线程放弃对该同步监视器的锁定后才能执行被此方法唤醒的线程)
下面是使用Lock对象来保证同步的方法
await()
- 必须通过Condition来调用这个方法
- 类式隐式同步监视器上的wait(),导致当前线程等待,知道其他线程调用该Condition的signal()或者signalAll()来唤醒此线程
signal()
- 必须通过Condition来调用这个方法
- 唤醒此Lock对象上等待的单个线程。(只有当线程放弃该Lock对象的锁定后才可以执行被此方法唤醒的线程)
方法总结
- 程序调用sleep,yield来暂停当前线程执行,当前线程不会释放同步监视器。
- 当前线程的suspend()被别的线程调用,该线程不会释放同步监视器。
- 程序执行了同步监视器对象的wait(),则当前线程暂停并释放同步监视器。
- wait()notify() notifyAll()都必须通过同步监视器来调用这个方法(同步代码块是括号里的对象,同步方法是调用者)
- await()signal() signalAll()都必须通过同步监视器来调用这个方法(同步代码块是括号里的对象,同步方法是调用者)
线程同步(同步监视器、同步方法)
- 线程同步,就是我在处理某件事情的时候,其他线程也来处理这件事,此时他们只能在外面等待,直到我处理完这件事情
同步监视器
- 可以用同步监视器来实现线程同步,使用同步监视器的通用方法就是同步代码块
- 当多个线程进入同步代码块之前,必须要获得同步监视器,任何时刻只能有一个线程能获得,未获得的只能在同步代码块外面等着,执行完同步代码块就会释放对同步监视器的锁定
- 任何对象都可以作为同步监视器,但是建议用可能被并发访问的共享资源作为同步监视器,synchronized(obj){ } 中obj就是同步监视器
同步方法
- 使用同步监视器还可以用同步方法,同步方法就是用synchronized修饰的方法,此时无需显式指定同步监视器,同步方法的同步监视器就是this,即调用这个方法的对象
区别
- 多个线程的执行体都在run或者call,对共享资源的操作都要在run才能被执行。同步代码块没有名字可以调用,所以全部写在run里;而同步方法则可以写在共享数据所在的类里,然后run方法去调用即可
- 同步方法这种在资源所在的类定义对该资源操作的对应方法,而不是直接在run里实现取钱逻辑更符合面向对象规则
线程通信
- 虽然无法准确控制线程轮换执行,但我们还是可以通过一些机制来保证线程协调执行。比如让AB交替执行,而不能连续执行A或B。
使用synchronized关键字来保证线程同步
为实现这种功能,可以借助Object类的wait(),notify(),notifyAll(),这三个方法必须由同步监视器来调用(同步代码块是括号里的对象,同步方法是调用者)
使用Lock对象来保证同步
- 如果程序不使用synchronized关键字来保证线程同步,而是直接用Lock对象来保证同步。那么就没有同步监视器了,也就不能用wait,notify
notifyall方法了(三个方法都必须由同步监视器调用),因此,java提供了一个Condition类来保持协调,Condition可以让得到Lock对象的线程释放Lock对象,也可以唤醒其它正处于等待的线程。 - Lock替代了同步代码块或同步方法,Condition替代了同步监视器的功能
- Condition提供了await()让得到Lock对象的线程释放Lock对象,提供了signal(),signalAll()唤醒其它正处于等待此Lock对象的线程。
- 通过调用Lock对象的newConditiom()方法即可获得lock实例的condition实例
|