wait线程等待:
- wait的功能和sleep类似,都是让线程暂停执行任务,但是其实是两个完全不同的方法。
- sleep是Thread类中的方法,让当前线程中的实例对象暂停执行任务,进入阻塞状态。
- wait是Object类的方法,所以它不是针对线程对象的方法,而实针对线程对象要访问的资源对象的方法。
- 即调用A对象的wait方法表示,让当前正在访问A对象的线程暂停,同时它有一个前提,当前线程对象必须拥有A对象,所以wait方法只能在同步方法或同步代码块中使用,否则就会抛出IllegaiMonitorStateException异常。
如何解除wait造成的阻塞?
- 指定 wait 时间,调用wait(long millis)即可。mills毫秒之后会自动解除阻塞,和sleeping(long millis)类似的方法。
- 调用notify,来唤醒线程。
package day_4_14;
public class Test {
public static void main(String[] args) {
A a = new A();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
a.test(i);
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
a.test2();
}
}).start();
}
}
class A{
public synchronized void test(int i) {
if(i == 2) {
try {
this.wait(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(i == 5) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i + "----A");
}
public synchronized void test2() {
this.notify();
}
}
生产者消费者模型
package com.chenny;
public class Hamburger {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Hamburger(int id) {
this.id = id;
}
@Override
public String toString() {
return "Hamburger [id=" + id + "]";
}
}
package com.chenny;
public class SyncStack {
public Hamburger[] hamburgers = new Hamburger[6];
public int index = 0;
public synchronized void push(Hamburger hamburger) {
while (index == hamburgers.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
hamburgers[index] = hamburger;
index++;
System.out.println("生产了一个汉堡:" + hamburger);
}
public synchronized Hamburger pop() {
while (index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
index--;
System.out.println("消费了一个汉堡:" + hamburgers[index]);
return hamburgers[index];
}
}
package com.chenny;
public class Produce implements Runnable {
private SyncStack syncStack = null;
public Produce(SyncStack syncStack) {
this.syncStack = syncStack;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
Hamburger hamburger = new Hamburger(i);
this.syncStack.push(hamburger);
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.chenny;
public class Consumer implements Runnable {
private SyncStack syncStack;
public Consumer(SyncStack syncStack) {
this.syncStack = syncStack;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
this.syncStack.pop();
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.chenny;
public class Main {
public static void main(String[] args) {
SyncStack syncStack = new SyncStack();
Produce produce = new Produce(syncStack);
Consumer consumer = new Consumer(syncStack);
new Thread(produce).start();
new Thread(consumer).start();
}
}