在object类方法当中,主要对wait和notify两个大类的办法有提示,如果做简单的学习可以只记住这几个办法即可
void notify()
唤醒在此对象监视器上等待的单个线程
void notifyAll()
唤醒在此对象监视器上等待的所有线程
void wait( )
导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法
void wait(long timeout)
导致当前的线程等待,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者指定的时间过完。
void wait(long timeout, int nanos)
导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法,或者其他线程打断了当前线程,或者指定的时间过完。
但要注意,在官方文档中,wait和notify这些并不是直属于Thread类,而是存在直属在object类,所以说在使用调度对象的时候,要注意,每一个对象都是存在这些的功能,因为每一个对象都有锁,锁是对对象的基础。
在这里可能存在疑惑,面对锁的概念。提前声明,锁是一个大体但重要的概念,在锁的下面还会具体的区分出来如乐观锁,悲观锁什么的。所以并不一定需要记住太多的锁的东西
但大体的概念是需要理解和记忆的锁就是用来控制多个线程访问共享资源的方式,简单来说,一个锁能够防止多个线程同时访问共享资源。
相应的在线程进程当中也有相似的原理,线程是操作系统能够进行运算调度的最小单位,进程则是进程则是系统进行资源分配和调度 的最小单位
所以可以得知,在运算系统调用这些都对象的时候,需要对可能出现的竞争对手进行加锁处理,不然很容易出现系统中的报错,即使是使用throws IllegalMonitorStateException方法进行处理,也不一定会做到正确的处理,因为可能会出现线程调度对象出现时间上的错位
所以要注意在使用wait()办法的时候要先给这个锁对象的控制权,这个位置一般需要使用synchronized
一般情况下需要在循环当中使用wait这样可以确保在程序运行的过程中会在线程运行暂停回复之后都检查wait的条件,确保wait会正确的被唤醒
notify()方法在通知唤醒的时候和想象中的不太一样,在唤醒的时候会先唤醒其中等待数列的第一个而不是优先级第一位的相关线程。
notifyAll( )通知所有等待该竞争资源的线程(也不会按照线程的优先级来执行)(所以我不理解为什么要设置过多的优先级)
针对obj锁,其实是lock锁,使用办法也很简单
void lock(): 执行此方法时, 如果锁处于空闲状态, 当前线程将获取到锁
lock()方法则是一定要获取到锁, 如果锁不可用, 就一直等待, 在未获得锁之前,当前线程并不继续向下执行.
boolean tryLock():如果锁可用, 则获取锁, 并立即返回 true, 否则返回 false.
tryLock()只是"试图"获取锁, 如果锁不可用, 不会导致当前线程阻塞挂起,当前线程仍然继续往下执行代码.
void unlock() 解锁
isLock():此锁是否有任意线程占用
public class WaitNotifyTest {
// 在多线程间共享的对象上使用wait
private String[] shareObj = { "true" };
public static void main(String[] args) {
WaitNotifyTest test = new WaitNotifyTest();
ThreadWait threadWait1 = test.new ThreadWait("wait thread1");
threadWait1.setPriority(2);
ThreadWait threadWait2 = test.new ThreadWait("wait thread2");
threadWait2.setPriority(3);
ThreadWait threadWait3 = test.new ThreadWait("wait thread3");
threadWait3.setPriority(4);
ThreadNotify threadNotify = test.new ThreadNotify("notify thread");
threadNotify.start();
threadWait1.start();
threadWait2.start();
threadWait3.start();
}
class ThreadWait extends Thread {
public ThreadWait(String name){
super(name);
}
public void run() {
synchronized (shareObj) {
while ("true".equals(shareObj[0])) {
System.out.println("线程"+ this.getName() + "开始等待");
long startTime = System.currentTimeMillis();
try {
shareObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("线程" + this.getName()
+ "等待时间为:" + (endTime - startTime));
}
}
System.out.println("线程" + getName() + "等待结束");
}
}
class ThreadNotify extends Thread {
public ThreadNotify(String name){
super(name);
}
public void run() {
try {
// 给等待线程等待时间
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (shareObj) {
System.out.println("线程" + this.getName() + "开始准备通知");
shareObj[0] = "false";
shareObj.notifyAll();
System.out.println("线程" + this.getName() + "通知结束");
}
System.out.println("线程" + this.getName() + "运行结束");
}
}
}