线程的协调工作

       学习操作系统的时候,有碰到生产者和消费者问题,生产者往单个缓冲区中送产品,只有等消费者消费完了,才能继续往缓冲区中添加产品。消费者消费缓冲区中的产品,只有缓冲区中有产品,他才能消费。

     java中的 Object类有三个方法,wait(),notify(),notifyAll()。我们可以利用者三个方法实现线程的协调工作。这三个方法必须有同步监视器调用,否则会产生错误。

    wait()的作用是导致该线程等待,直到其他线程调用该同步监视器的notify()或者notifyAll()方法,来唤醒该线程。

   notify()唤醒该同步监视器上的一个线程,选择是随意性的。只能唤醒调用wait()后等待的线程。

   notifyAll()唤醒该同步监视器上的所有线程。

    下面演示一个程序,模拟账户取现和存钱,用户1往账户里存钱,必须等待用户2取现完才能往里继续存钱。用户2必须等用户1存完钱才能取现。

    我们可以设置一个标志,flag来表示当前是否可以存钱或者取钱,flag=false,表示可以存钱,不能取钱。flag=true,表示当前可以取钱,不能存钱。用户存完钱后,设置flag=true,并且调用notifyAll唤醒其他线程。用户取完钱后,设置flag=false,并且调用notifyAll唤醒其他线程。

   下面是程序的代码:

   首先是一个账户类,可以实现存钱和取现。

   

class Account{
	
	int blance;
    
	//false不是没钱
	boolean flag=false;
	
	public Account(int blance) {
		super();
		this.blance = blance;
	}

	public int getBlance() {
		return blance;
	}

	public void setBlance(int blance) {
		this.blance = blance;
	}
	//定义取款操作
	public  synchronized  void withdraw(int money)
	{  
		if(flag==false)
		{
	       try {
			this.wait();
		   } catch (InterruptedException e) {
			e.printStackTrace();
		   } 
		}
		else
		{
			System.out.println("我正在取钱");
			flag =false;
			this.notifyAll();
		}
	}
	//定义存钱
	public synchronized void desopit()
	{
		if(flag)
		{
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		else
		{
			System.out.println("我正在存钱");
			flag=true;
			this.notifyAll();
		}
	}
}

模拟一个取现的线程

class Consumer extends Thread
{
    Account a;
    
	public Consumer(Account a) {
		super();
		this.a = a;
	}

	public  void run() {
		//取现
		for(int i=0;i<100;i++)
		{
		   a.withdraw(100);
		}
	}
	
}

存钱的线程

class Product extends Thread
{
	Account a;
	
	public Product(Account a) {
		super();
		this.a = a;
	}

	@Override
	public  void   run() {
		//存钱
		for(int i=0;i<100;i++)
		{
			a.desopit();
		}
	}
	
}

测试类

public class Testhezuo {

	public static void main(String[] args) {
		Account a = new Account(0);
		Consumer c1= new Consumer(a);
		c1.start();
		
		Consumer c2= new Consumer(a);
		c2.start();
		
		Consumer c3= new Consumer(a);
		c3.start();
		
		Product p = new Product(a);
		p.start();
	}

}

可以看到如下输出结果

我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱
我正在存钱
我正在取钱

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
互斥锁可以用来协调多个线程工作顺序,实现同步操作。当多个线程需要访问共享资源时,使用互斥锁可以保证同一时刻只有一个线程可以访问共享资源,从而避免多个线程同时修改共享资源导致的数据不一致问题。 以下是使用互斥锁协调多个线程工作顺序的示例: 1. 定义一个互斥锁对象 ```c++ std::mutex mtx; ``` 2. 在需要访问共享资源的代码块前加锁 ```c++ mtx.lock(); // 访问共享资源的代码块 mtx.unlock(); ``` 3. 确保访问共享资源的代码块执行完毕后解锁 ```c++ mtx.lock(); // 访问共享资源的代码块 mtx.unlock(); ``` 4. 保证所有线程都按照指定的顺序执行 例如,假设有三个线程 A、B、C,需要按照 A -> B -> C 的顺序执行,可以使用如下代码: ```c++ #include <mutex> #include <thread> std::mutex mtx; void threadA() { mtx.lock(); // 线程 A 的代码 mtx.unlock(); } void threadB() { mtx.lock(); // 线程 B 的代码 mtx.unlock(); } void threadC() { mtx.lock(); // 线程 C 的代码 mtx.unlock(); } int main() { std::thread tA(threadA); std::thread tB(threadB); std::thread tC(threadC); tA.join(); tB.join(); tC.join(); return 0; } ``` 在该示例中,使用互斥锁 mtx 来保证线程 A、B、C 按照 A -> B -> C 的顺序执行。线程 A 在执行之前会先锁定互斥锁 mtx,执行完毕后再解锁,这样就保证了线程 B 和 C 在 A 执行完毕之前无法执行。同理,线程 B 和 C 也会在执行之前锁定互斥锁 mtx,执行完毕后再解锁,从而保证了线程执行的顺序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值