欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用lock方法代替synchronized方法,并使用await和signal方法替代wait和notifyall方法。

程序员文章站 2022-05-03 20:57:38
...

不知不觉学了很久的java了。今天是第一次写博客,可能写的不好,希望看到的人,能够指导和指正!

为什么需要使用lock方法替换synchronized呢?

首先呢,我们大家都知道synchronized是java内置的关键字,是规定好的,我们无法去改变其内容的。虽然他很方便和强大,但是局限性也比较强,很多时候并不适合用。而lock呢?拥有更大的*度,所以灵活度更高。使用的场合更多。

lock和synchronized的区别在哪里?

使用lock方法代替synchronized方法,并使用await和signal方法替代wait和notifyall方法。

先看看原来的synchronized方法

public class Person {

	private String name;
	private String sex;
	private boolean flag = false;//当他为false时代表着需要被设置
/**
 * 设置方法
 * @param name
 * @param sex
 */
	public synchronized void setPerson(String name, String sex) {
		while (flag) {//  flag= true的是让他等待。
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}// 所有当他 flag = flase时 设置参数
		this.name = name;
		this.sex = sex;
		flag = true;
		notifyAll();	
		}
	/**
	 * 获取name和sex的方法
	 */
	public synchronized void getPerson() {
		while(!flag) {//
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
			}
		System.out.println(Thread.currentThread().getName()+name +","+sex);
		flag = false;
		notifyAll();
		}
	}
	

这是synchronized结合wait和notifyall方法。

这是lock结合await和signalall方法

public class Person2 { // 2方便和原来的对比

	private String name;
	private String sex;
	private boolean flag = false;

	Lock lock = new ReentrantLock();//这里需要new处理一个renntrantlock对象,因为lock方法是这个对象所有的。
	Condition con = lock.newCondition();//通过lock得到一个监视器condition。
	public void setPerson(String name, String sex) {
		
		lock.lock();//lock就是上锁的行为
		try {
			while (flag) {
				con.await();//await方法我觉得在这里基本上等同wait方法
			}
			this.name = name;
			this.sex = sex;
			flag = true;
			con.signalAll();//signalAll是唤醒其他所有线程的方法等同于notify方法
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {//有这个finally代表着不过是否有错误都要进行unlock。
			lock.unlock();
		}
	}

	public void getPerson() {//这是获取name和sex的方法,下面的如上
		lock.lock();
		try {
			while (!flag) {
				con.await();
			}
			System.out.println(name + "," + sex);
			flag = false;
			con.signalAll();
			;
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

}

创建一个获取的类

public class ShowPerson implements Runnable {
	private Person p;
	
	public ShowPerson(Person p) {
		super();
		this.p = p;
	}
	public  void show() {
		p.getPerson();
	
	}
	
	@Override
	public void run() {
		while(true) {
		show();//run里面调用显示方法
	}}

}

创建一个设置name个sex的类

public class MedifyPerson implements Runnable {
	private Person p;
	private int r;

	public MedifyPerson(Person p) {
		super();
		this.p = p;
	
	}

	public  void medify() {
		r = (int) (Math.random() * 100);//设置一个0-99随机数

		if (r > 50)//如果大于50则设置张三,男
			p.setPerson("张三", "男");

		else {//其他设置李四,女
			p.setPerson("李四", "女");
		}

	}

	@Override
	public void run() {
		while(true) {
		medify();//run里面调用设置方法
		}
	}
}

双线程测试一下

public class TestPerson {
	
	public static void main(String[] args) {
		 Person p = new Person();
		MedifyPerson mp = new MedifyPerson(p);
		ShowPerson sp = new ShowPerson(p);
		Thread th1 = new Thread(mp);
		Thread th2 = new Thread(sp);
		th1.start();
		th2.start();
	}

}

可以发现用lock方法可以完美取代synchronized方法。