Object中wait带参方法和notifyAll方法
进入到Timewaiting(计时等待)有两种方式
1.使用sleep(Long m)方法,在毫秒值结束之后,线程睡醒进入到Runnable/BLocked状态
2.使用wait(Long m)方法, wait方法如果在毫秒值结束之后,还没有被notify确醒,就会自动醒来,线程睡醒进入到Runnable/BLocked状态
public class Demo01WaitAndNotify {
public static void main(String[] args) {
//创建锁对象,保证唯一
Object obj = new Object();
//创建一个顾客线程(消费者)
new Thread(){
@Override
public void run() {
while (true){
//保证等待和唤醒只能有一个在执行需要使用名捕时间
synchronized (obj){
System.out.println("告诉老板要的数量");
//调用wait()方法,进入无限等待状态
try {
obj.wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("开吃");
}
}
}
}.start();
//创建一个老板线程(生产者)
new Thread(){
@Override
public void run() {
while (true){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//保证等待和唤醒只能有一个在执行需要使用名捕时间
synchronized (obj){
System.out.println("花了5秒做包子,做好包子之后,告诉顾客,可以吃了");
obj.notify();
}
}
}
}.start();
}
}
在使用带参的wait方法后他会在指定时间后自动解除等待状态
Object中notifyAll方法
public class Demo01WaitAndNotify {
public static void main(String[] args) {
//创建锁对象,保证唯一
Object obj = new Object();
//创建一个顾客线程(消费者)
new Thread(){
@Override
public void run() {
while (true){
//保证等待和唤醒只能有一个在执行需要使用名捕时间
synchronized (obj){
System.out.println("顾客1告诉老板要的数量");
//调用wait()方法,进入无限等待状态
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("顾客1开吃");
}
}
}
}.start();
//创建一个顾客线程(消费者)
new Thread(){
@Override
public void run() {
while (true){
//保证等待和唤醒只能有一个在执行需要使用名捕时间
synchronized (obj){
System.out.println("顾客2告诉老板要的数量");
//调用wait()方法,进入无限等待状态
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("顾客2开吃");
}
}
}
}.start();
//创建一个老板线程(生产者)
new Thread(){
@Override
public void run() {
while (true){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//保证等待和唤醒只能有一个在执行需要使用名捕时间
synchronized (obj){
System.out.println("花了5秒做包子,做好包子之后,告诉顾客,可以吃了");
obj.notify();
}
}
}
}.start();
}
}
当有两个顾客时使用notify会先解除先wait的线程,而且一次只会解除一个线程,不会解除多个
当使用notifyAll时:
//创建一个老板线程(生产者)
new Thread(){
@Override
public void run() {
while (true){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//保证等待和唤醒只能有一个在执行需要使用名捕时间
synchronized (obj){
System.out.println("花了5秒做包子,做好包子之后,告诉顾客,可以吃了");
// obj.notify();
obj.notifyAll();
}
}
}
}.start();
notifyAll会解除所有正在等待的线程
线程间通信
概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)不同
为什么要处理线程间通信:
多个线程并发执行时,在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务,
并且我们希望他们有规律的执行,那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据.
如何保证线程间通信有效利用资源∶
多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个变量的使用或操作。
就是多个钱程在操作同一份数据时,避免对同一共享变量的争夺。
也就是我们需要通过一定的手段使各个线程能有效的利用资源。而这种手段即—―等待唤醒机制。