wait()
方法又叫痴汉方法,就是使线程停止运行,会释放对象锁
package 生产者消费者模型;
class MyThread implements Runnable{
private String str = new String();
@Override
public void run() {
synchronized(str){
System.out.println("wait方法开始...");
try {
str.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait方法结束...");
}
}
}
public class Test {
public static void main(String[] args){
MyThread mt = new MyThread();
Thread thread = new Thread(mt);
thread.start();
}
}
执行结果:
wait方法开始…
如果到了预计时间还未被唤醒,线程将继续执行
package 生产者消费者模型;
class MyThread implements Runnable{
private String str = new String();
@Override
public void run() {
synchronized(str){
System.out.println("wait方法开始...");
try {
//等待1s如果未被唤醒、线程继续执行
str.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait方法结束...");
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
MyThread mt = new MyThread();
Thread thread = new Thread(mt);
thread.start();
}
}
执行结果:
wait方法开始…
wait方法结束…
wait()之后线程继续执行有两种方法:
package 生产者消费者模型;
class MyThread implements Runnable{
private String str = new String();
@Override
public void run() {
synchronized(str){
System.out.println("wait方法开始...");
try {
str.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait方法结束...");
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
MyThread mt = new MyThread();
Thread thread = new Thread(mt);
thread.start();
Thread.sleep(2000);
thread.interrupt();
}
}
package 生产者消费者模型;
class MyThread implements Runnable{
private Object object ;
private boolean flag;
public MyThread(Object object, boolean flag) {
this.object = object;
this.flag = flag;
}
public void waitMethod()
{
synchronized (object)
{
System.out.println("wait方法开始.."+Thread.currentThread().getName());
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait方法结束.."+Thread.currentThread().getName());
}
}
public void notifyMethod()
{
synchronized (object)
{
System.out.println("notify方法开始..."+Thread.currentThread().getName());
object.notify();
System.out.println("notify方法结束..."+Thread.currentThread().getName());
}
}
@Override
public void run() {
if(flag){
waitMethod();
}else{
notifyMethod();
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
Object object = new Object();
MyThread myThread1 = new MyThread(object,true);
MyThread myThread2 = new MyThread(object,false);
Thread waitThread1 = new Thread(myThread1,"等待线程");
Thread notifyThread2 = new Thread(myThread2,"唤醒线程");
waitThread1.start();
Thread.sleep(1000);
notifyThread2.start();
}
}
执行结果:
wait方法开始…等待线程
notify方法开始…唤醒线程
notify方法结束…唤醒线程
wait方法结束…等待线程
唤醒所有在该对象上的等待线程
package 生产者消费者模型;
class MyThread implements Runnable{
private Object object ;
private boolean flag;
public MyThread(Object object, boolean flag) {
this.object = object;
this.flag = flag;
}
public void waitMethod()
{
synchronized (object)
{
System.out.println("wait方法开始.."+Thread.currentThread().getName());
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait方法结束.."+Thread.currentThread().getName());
}
}
public void notifyMethod()
{
synchronized (object)
{
System.out.println("notify方法开始..."+Thread.currentThread().getName());
object.notifyAll();
System.out.println("notify方法结束..."+Thread.currentThread().getName());
}
}
@Override
public void run() {
if(flag){
waitMethod();
}else{
notifyMethod();
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
Object object = new Object();
MyThread myThread1 = new MyThread(object,true);
MyThread myThread2 = new MyThread(object,false);
for(int i=0 ;i<10;i++)
{
Thread waitThreadi = new Thread(myThread1,"等待线程"+i);
waitThreadi.start();
}
Thread notifyThread2 = new Thread(myThread2,"唤醒线程");
Thread.sleep(1000);
notifyThread2.start();
}
}
执行结果:
wait方法开始…等待线程1
wait方法开始…等待线程0
wait方法开始…等待线程2
wait方法开始…等待线程5
wait方法开始…等待线程4
wait方法开始…等待线程3
wait方法开始…等待线程6
wait方法开始…等待线程9
wait方法开始…等待线程7
wait方法开始…等待线程8
notify方法开始…唤醒线程
notify方法结束…唤醒线程
wait方法结束…等待线程8
wait方法结束…等待线程7
wait方法结束…等待线程9
wait方法结束…等待线程6
wait方法结束…等待线程3
wait方法结束…等待线程4
wait方法结束…等待线程5
wait方法结束…等待线程2
wait方法结束…等待线程0
wait方法结束…等待线程1
生产者与消费者模型一共有三种关系:生产者与生产者的互斥关系,消费者与消费者的互斥关系,生产者与消费者的互斥且同步关系。
package 生产者消费者模型;
//货物类
class Goods {
private String goods;
private int count;
public Goods(String goods) {
this.goods = goods;
}
/**
* 生产者生产货物的方法
*/
public synchronized void produce(){
if(count > 0){
System.out.println("该商品还有库存....");
//生产者等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有库存 商品数量+1
this.count++;
System.out.println(Thread.currentThread().getName()+"生产产品"+toString());
//唤醒消费者
notify();
}
/**
* 消费者消费商品
*/
public synchronized void consumer(){
//防止消费者线程先启动 造成count称为负数
if(count == 0){
System.out.println("仓库已kong...");
//消费者等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//消费商品 数量-1
this.count--;
System.out.println(Thread.currentThread().getName()+"消费产品"+toString());
//唤醒生产者
notify();
}
@Override
public String toString() {
return "Goods{" +
"goods='" + goods + '\'' +
", count=" + count +
'}';
}
}
//生产者线程
class Producer implements Runnable{
//生产的货物
private Goods good;
public Producer(Goods good) {
this.good = good;
}
@Override
public void run() {
this.good.produce();
}
}
//消费者线程
class Consumer implements Runnable{
//消费的货物
private Goods good;
public Consumer(Goods good) {
this.good = good;
}
@Override
public void run() {
this.good.consumer();
}
}
public class Test{
public static void main(String[] args) {
Goods goods = new Goods("特百惠杯子");
Producer producer = new Producer(goods);
Consumer consumer = new Consumer(goods);
Thread producerThread = new Thread(producer,"生产者");
Thread consumerThread = new Thread(consumer,"消费者");
consumerThread.start();
producerThread.start();
}
}
现实生活中肯定不是只存在一个生产者和一个消费者,生产者生产商品也肯定不是只生产一个,所以有多个生产者多个消费者的情况
package 生产者消费者模型;
import java.util.ArrayList;
import java.util.List;
//货物类
class Goods {
private String goods;
private int count;
public Goods(String goods) {
this.goods = goods;
}
/**
* 生产者生产货物的方法
*/
public synchronized void produce(){
//不断判断执行条件
/**
* 因为有多个线程 假设现在已有商品,生产者线程均在等待
* 消费者线程唤醒生产者线程后,假设此时生产者线程1生产产品
* 此时count=1,若用if判断会造成count数量一直增加
*/
while(count > 0){
System.out.println("该商品还有库存....");
//生产者等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有库存 商品数量+1
this.count++;
System.out.println(Thread.currentThread().getName()+"生产产品"+toString());
//唤醒所有消费者
notifyAll();
}
/**
* 消费者消费商品
*/
public synchronized void consumer(){
//不断判断执行条件
/**因为有多个线程 假设消费者线程先执行、由于不止一个消费者
* 此时可能有多个消费者在等待,如果此时一个生产者生产了商品
* 消费者线程均被唤醒、如果此时线程2消费产品 此时若用if判断
* 其余等待线程也会count-- 造成错误 所以需要用while判断
*/
while(count == 0){
System.out.println("仓库已空...");
//消费者等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//消费商品 数量-1
this.count--;
System.out.println(Thread.currentThread().getName()+"消费产品"+toString());
//唤醒所有生产者
notifyAll();
}
@Override
public String toString() {
return "Goods{" +
"goods='" + goods + '\'' +
", count=" + count +
'}';
}
}
//生产者线程
class Producer implements Runnable{
//生产的货物
private Goods goods;
public Producer(Goods goods) {
this.goods = goods;
}
@Override
public void run() {
while(true){
this.goods.produce();
}
}
}
//消费者线程
class Consumer implements Runnable{
//消费的货物
private Goods goods;
public Consumer(Goods goods) {
this.goods = goods;
}
@Override
public void run() {
while(true){
this.goods.consumer();
}
}
}
public class Test{
public static void main(String[] args) {
Goods goods = new Goods("特百惠杯子");
List<Thread> list = new ArrayList<>();
for(int i=0;i<10;i++){
Thread thread = new Thread(new Producer(goods),"生产者"+i);
list.add(thread);
}
for(int i=0;i<5;i++){
Thread thread = new Thread(new Consumer(goods),"消费者"+i);
list.add(thread);
}
for(Thread thread:list){
//消费者、生产者谁先启动不一定
thread.start();
}
}
}
package 生产者消费者模型;
import java.util.ArrayList;
import java.util.List;
//货物类
class Goods {
private String goods;
private int count;
public Goods(String goods) {
this.goods = goods;
}
public int getCount() {
return count;
}
/**
* 生产者生产货物的方法
*/
public synchronized void produce(){
//如果没有库存 商品数量+1
if(this.count<10){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.count++;
System.out.println(Thread.currentThread().getName()+"生产产品"+toString());
}
//唤醒所有消费者
notifyAll();
}
/**
* 消费者消费商品
*/
public synchronized void consumer(){
//不断判断执行条件
/**因为有多个线程 假设消费者线程先执行、由于不止一个消费者
* 此时可能有多个消费者在等待,如果此时一个生产者生产了商品
* 消费者线程均被唤醒、如果此时线程2消费产品 此时若用if判断
* 其余等待线程也会count-- 造成错误 所以需要用while判断
*/
while(count == 0){
System.out.println("仓库已空...");
//消费者等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//消费商品 数量-1
this.count--;
System.out.println(Thread.currentThread().getName()+"消费产品"+toString());
//唤醒所有生产者
notifyAll();
}
@Override
public String toString() {
return "Goods{" +
"goods='" + goods + '\'' +
", count=" + count +
'}';
}
}
//生产者线程
class Producer implements Runnable{
//生产的货物
private Goods goods;
public Producer(Goods goods) {
this.goods = goods;
}
@Override
public void run() {
//最大库存为10
while(true){
this.goods.produce();
}
}
}
//消费者线程
class Consumer implements Runnable{
//消费的货物
private Goods goods;
public Consumer(Goods goods) {
this.goods = goods;
}
@Override
public void run() {
while(true){
this.goods.consumer();
}
}
}
public class Test{
public static void main(String[] args) {
Goods goods = new Goods("特百惠杯子");
List<Thread> list = new ArrayList<>();
for(int i=0;i<10;i++){
Thread thread = new Thread(new Producer(goods),"生产者"+i);
list.add(thread);
}
for(int i=0;i<5;i++){
Thread thread = new Thread(new Consumer(goods),"消费者"+i);
list.add(thread);
}
for(Thread thread:list){
//消费者、生产者谁先启动不一定
thread.start();
}
}
}