文章目录

🔐多线程通信

(1).🔓由来

(2).🔓成员方法 

(3).🔓案例引入

(4).🔓代码实现


【Java】详解多线程通信-LMLPHP


🔐多线程通信

(1).🔓由来

      现代社会崇尚合作精神,分工合作在日常生活和工作中无处不在。举个简单的例子,例如一条生产线的上下两个工序,它们必须以规定的速率完成各自的工作,才能保证产品在流水线中顺利的流转。如果下工序过慢,会造成产品在两道工序之间的积压,如果上工序过慢,会造成下工序长时间无事可做。在多线程的程序中,上下工序可以看作两个线程,这两个线程之间需要协同完成工作,就需要线程之间进行通信。

思路:

      如果想解决上述线程执行不一致的问题,就需要控制多个线程按照一定的顺序轮流执行,此时就需要让线程间进行通信保证线程任务的协调进行

解决:

      为此,Java在Object类中提供了wait()notify()notifyAll()等方法用于解决线程间的通信问题,因为Java中所有类都是Object类的子类或间接子类,因此任何类的实例对象都可以直接使用这些方法。

(2).🔓成员方法 

【Java】详解多线程通信-LMLPHP

说明:

     其中wait()方法用于使当前线程进入等待状态,notify()和notifyAll()方法用于唤醒当前处于等待状态的线程。

注意:

     wait()、notify()和notifyAll()方法的调用者都应该是同步锁对象,如果这三个方法的调用者不是同步锁对象,Java虚拟机就会抛出IllegalMonitorStateException异常。 

(3).🔓案例引入

【Java】详解多线程通信-LMLPHP

(4).🔓代码实现

代码如下👇🏻 

package Pro;

public class Clerk {
	private int product=20;   //共享资源
	//从生产者线程获取资源
	public synchronized void addProduct(){
		if(product>=20){
			try {
				this.wait();//生产者线程等待,释放锁资源
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}else{
			product++;
			System.out.println("生产者生产第" + product + "个产品");
			this.notifyAll();
			
		}
	}
	//将资源卖给消费者线程
	public synchronized void sellProduct(){
		if(product<=0){
			try {
				this.wait();//消费者线程等待,释放锁资源
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}else{	
			System.out.println("消费者消费第"+product+"个产品");
			product--;
			this.notifyAll();
		}
		
	}

}

package Pro;

public class ProducerThread implements Runnable {
	Clerk clerk;
	
	public ProducerThread(Clerk clerk) {
		super();
		this.clerk = clerk;
	}

	@Override
	public void run() {
		while(true){
			clerk.addProduct();
			try {
				Thread.sleep((int)(Math.random()*10)*100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}

}
package Pro;

public class ConsumerThread implements Runnable {
	Clerk clerk;
	
	public ConsumerThread(Clerk clerk) {
		super();
		this.clerk = clerk;
	}

	@Override
	public void run() {
		while(true){
			clerk.sellProduct();
			try {
				Thread.sleep((int)(Math.random()*10)*100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}

}
package Pro;

public class Demo {
	public static void main(String[] args) {
		Clerk c=new Clerk();
		new Thread(new ProducerThread(c), "生产者线程甲").start();
		new Thread(new ProducerThread(c), "生产者线程乙").start();
		new Thread(new ConsumerThread(c),"消费者线程甲").start();
		new Thread(new ConsumerThread(c),"消费者线程乙").start();
//		ProducerThread pt =new ProducerThread(c);
//		Thread t1=new Thread(pt, "生产者线程甲");
//		Thread t2=new Thread(pt, "生产者线程乙");
//		ConsumerThread ct =new ConsumerThread(c);
//		Thread t3=new Thread(ct,"消费者线程甲");
//		Thread t4=new Thread(ct,"消费者线程乙");
//		t1.start();
//		t2.start();
//		t3.start();
//		t4.start();
		
	}

}

思考:

为什么这些方法不定义在Thread类而是Object类中呢?

      这些方法的调用必须通过锁对象调用,而Object类对象代表任意的对象。所以,这些方法必须定义在Object类中。


11-17 08:56