多线程访问同一资源第三步 : 生产者和消费者模式 用synchronized

本文通过实例演示了如何使用synchronized关键字实现两个线程之间的同步,一个线程负责输入数据,另一个线程负责打印数据,确保了数据的一致性和同步性。
package cn.sdut.threadclass;

/*
 * 
 *             多线程访问同一资源第三步 : 线程设置 以及线程 线程打印   用synchronized
 * 两个线程:(注意这里是两个线程 ,多个线程  只需要把 notify 改成 notifyAll)
 *           一个线程输入  
 *           另一个线程打印
 *                      实现  输入一个  打印一个的效果
 */
class Person1 { // 这里是共同的资源 而且设置和输出数据都在里面进行            对数据进行操作时 需要进行 同步
	private String name;
	private char sex;
	private boolean flag = false;// 与上一篇不同的是 我们这里添加了一个 flag 用来判断是应该 输入 还是 打印

	public synchronized void setAttribute(String name, char sex) {

		while (flag) { // 如果 flag 为 true就说明已经输入了一条数据了 ,就让准备再塞入数据的线程休眠 等待打印完唤醒它   使用while判断更加安全
			try {
				this.wait(); // 线程wait()后 会自动放弃锁 而 sleep()不会放弃锁     并且 一定要使用相同的锁对象  同步非静态方法的锁是this    同步静态方法的锁是类的class文件
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		this.name = name;
		this.sex = sex;
		flag = true;//设置 为true 表示 数据已经设置了  上面判断是否等待的时候就会判断到
		notify(); // notify 是随机唤醒一个线程 我们这里只有两个线程 那么肯定是唤醒另一个打印线程          notifyAll是唤醒所有线程
//		notifyAll();
	}

	public synchronized void printAttribute() {   // 同步 方法

		while (!flag) { // 如果 flag 为false就说明已经打印了一条数据了 ,就让准备再打印数据的线程休眠 等待输入完唤醒它
			try {
				this.wait(); // 线程wait()后 会自动放弃锁 而 sleep()不会放弃锁
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		System.out.println(this.name + "    " + this.sex);
		flag = false;
		notify();
//		notifyAll();
	}

}


// 实现 Runnable 接口 调用方法设置数据
class In implements Runnable {

	private Person1 person = null;

	public In(Person1 person) {
		this.person = person;
	}

	@Override
	public void run() {

		for (int i = 0; i < 500; i++) {

			if (i % 2 == 0) {
				person.setAttribute("柯南", '男');
			} else {
				person.setAttribute("少司命", '女');
			}
		}

	}

}

//实现 Runnable 接口 调用方法打印数据
class Out implements Runnable {

	private Person1 person = null;

	public Out(Person1 person) {
		this.person = person;
	}

	@Override
	public void run() {
		for (int i = 0; i < 500; i++) {
			person.printAttribute();
		}

	}

}

public class ThreadDemo03 {

	public static void main(String[] args) {
		Person1 person = new Person1();// 建立共享
		In in = new In(person);
		Out out = new Out(person);
		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);
		// Thread t3 = new Thread(in);
		// Thread t4 = new Thread(out);
		t1.start();
		t2.start();
	//	 t3.start();
	//	 t4.start();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值