使用lock方法代替synchronized方法,并使用await和signal方法替代wait和notifyall方法。
程序员文章站
2022-05-03 20:57:38
...
不知不觉学了很久的java了。今天是第一次写博客,可能写的不好,希望看到的人,能够指导和指正!
为什么需要使用lock方法替换synchronized呢?
首先呢,我们大家都知道synchronized是java内置的关键字,是规定好的,我们无法去改变其内容的。虽然他很方便和强大,但是局限性也比较强,很多时候并不适合用。而lock呢?拥有更大的*度,所以灵活度更高。使用的场合更多。
lock和synchronized的区别在哪里?
先看看原来的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();
}
}