需要理解锁是什么意思?
首先是发生在多线程的情况下;
线程a,线程b,共享资源share
?
例如,share的资源一次只能被一个对象操作,这时候需要一个东西来标识(也叫监视器)出来表明该资源已经有人(指的是线程)在使用了,请还要使用的人(指的是线程)进入等待(线程等待池/队列);
怎么实现呢?
synchronized关键字,配合一个唯一的东西,可以是类.class,也可以是对象本身;但注意的是必须是一个引用的数据类型,如包装类,obj等
?
?
1.生产者和消费者模式
代码演示:
?
重点练习1:
一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条。哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭.那思考必须 把两只筷子放回才可以思考.
?
重点练习2:
桌子上有一个空盘,允许存放1个水果.爸爸想其中放苹果也可以放橘子.儿子专门等吃橘子.女儿专门等吃苹果!
?
?
?
?
public class Demo {
?
????class FriutPlate {
????????String name;
?
????????public synchronized void addFriut(String name) throws InterruptedException {
????????????while (this.name != null) {
????????????????System.out.println("盘子里已经有" + this.name + "生产者暂停");
????????????????this.wait();
????????????}
????????????this.notifyAll();
????????????this.name = name;
????????????System.out.println("向水果盘中放入:" + name);
????????????Thread.sleep(100);
????????}
?
????????public synchronized String getFriut() throws InterruptedException {
????????????while (this.name == null) {
????????????????System.out.println("盘子无水果,消费者暂停");
????????????????this.wait();
????????????}
????????????this.notifyAll();
????????????System.out.println("盘子中的:" + name + "消费者准备消费");
????????????Thread.sleep(100);
????????????return name;
????????}
?
????????public void setNameNull() {
????????????name = null;
????????}
????}
?
????class ProductApple implements Runnable {
????????FriutPlate fp;
?
????????public ProductApple(FriutPlate fp) {
????????????this.fp = fp;
????????}
?
????????@Override
????????public void run() {
????????????try {
????????????????synchronized (fp) {
????????????????????while (true) {
????????????????????????// System.out.println("正在往里放苹果");
????????????????????????fp.addFriut("苹果");
????????????????????}
????????????????}
????????????} catch (InterruptedException e) {
????????????????e.printStackTrace();
????????????}
????????}
?
????}
?
????class ProductOrange implements Runnable {
????????FriutPlate fp;
?
????????public ProductOrange(FriutPlate fp) {
????????????this.fp = fp;
????????}
?
????????@Override
????????public void run() {
????????????try {
????????????????synchronized (fp) {
????????????????????while (true) {
????????????????????????// System.out.println("正在往里放橘子");
????????????????????????fp.addFriut("橘子");
????????????????????}
????????????????}
????????????} catch (InterruptedException e) {
????????????????e.printStackTrace();
????????????}
????????}
????}
?
????class ConsumerApple implements Runnable {
????????FriutPlate fp;
?
????????public ConsumerApple(FriutPlate fp) {
????????????this.fp = fp;
????????}
?
????????@Override
????????public void run() {
????????????while (true) {
????????????????synchronized (fp) {
????????????????????String friutName = null;
????????????????????try {
????????????????????????friutName = fp.getFriut();
????????????????????} catch (InterruptedException e1) {
????????????????????????// TODO Auto-generated catch block
????????????????????????e1.printStackTrace();
????????????????????}
????????????????????if ("苹果".equals(friutName)) {
????????????????????????System.out.println("儿子吃掉苹果");
????????????????????????fp.setNameNull();
????????????????????} else {
????????????????????????System.out.println("不是苹果,儿子不吃");
????????????????????????try {
????????????????????????????Thread.sleep(100);
????????????????????????} catch (InterruptedException e) {
????????????????????????????// TODO Auto-generated catch block
????????????????????????????e.printStackTrace();
????????????????????????}
????????????????????}
?
????????????????}
????????????}
????????}
?
????}
?
????class ConsumerOrange implements Runnable {
????????FriutPlate fp;
?
????????public ConsumerOrange(FriutPlate fp) {
????????????this.fp = fp;
????????}
?
????????@Override
????????public void run() {
????????????while (true) {
????????????????synchronized (fp) {
????????????????????String friutName = null;
????????????????????try {
????????????????????????friutName = fp.getFriut();
????????????????????} catch (InterruptedException e1) {
????????????????????????// TODO Auto-generated catch block
????????????????????????e1.printStackTrace();
????????????????????}
????????????????????if ("橘子".equals(friutName)) {
????????????????????????System.out.println("女儿吃掉橘子");
????????????????????????fp.setNameNull();
????????????????????} else {
????????????????????????System.out.println("不是橘子,女儿不吃");
????????????????????????try {
????????????????????????????Thread.sleep(100);
????????????????????????} catch (InterruptedException e) {
????????????????????????????// TODO Auto-generated catch block
????????????????????????????e.printStackTrace();
????????????????????????}
????????????????????}
?
????????????????}
????????????}
????????}
????}
?
????public static void main(String[] args) {
????????Demo d = new Demo();
????????FriutPlate fp = d.new FriutPlate();
?
????????ProductApple pa = d.new ProductApple(fp);
????????ProductOrange po = d.new ProductOrange(fp);
?
????????ConsumerApple ca = d.new ConsumerApple(fp);
????????ConsumerOrange co = d.new ConsumerOrange(fp);
?
????????Thread t1 = new Thread(pa);
????????Thread t2 = new Thread(po);
????????Thread t3 = new Thread(ca);
????????Thread t4 = new Thread(co);
?
????????t1.start();
????????t2.start();
????????t3.start();
????????t4.start();
?
????}
}
?
?
练习:三个线程轮流打印ABC
?
练习:死锁演示
?
1.当线程为2个时,锁为一个时,很少出现死锁
2.当线程为3个时,使用notify()唤醒,极大可能出现死锁
3.当线程A在sync(a)-sync(b)时,线程B在sync(b)-sync(a)时,这种嵌套锁,一定会出现死锁
原文:https://www.cnblogs.com/huadaxia/p/12293148.html