

需要理解锁是什么意思?
首先是发生在多线程的情况下;
线程a,线程b,共享资源share
例如,share的资源一次只能被一个对象操作,这时候需要一个东西来标识(也叫监视器)出来表明该资源已经有人(指的是线程)在使用了,请还要使用的人(指的是线程)进入等待(线程等待池/队列);
怎么实现呢?
synchronized关键字,配合一个唯一的东西,可以是类.class,也可以是对象本身;但注意的是必须是一个引用的数据类型,如包装类,obj等
1.生产者和消费者模式

代码演示:





重点练习1:

一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条。哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭.那思考必须 把两只筷子放回才可以思考.








重点练习2:
桌子上有一个空盘,允许存放1个水果.爸爸想其中放苹果也可以放橘子.儿子专门等吃橘子.女儿专门等吃苹果!

![]()


publicclassDemo {
classFriutPlate {
String name;
publicsynchronizedvoidaddFriut(String name) throwsInterruptedException {
while(this.name!= null) {
System.out.println("盘子里已经有"+ this.name+ "生产者暂停");
this.wait();
}
this.notifyAll();
this.name= name;
System.out.println("向水果盘中放入:"+ name);
Thread.sleep(100);
}
publicsynchronizedString getFriut() throwsInterruptedException {
while(this.name== null) {
System.out.println("盘子无水果,消费者暂停");
this.wait();
}
this.notifyAll();
System.out.println("盘子中的:"+ name+ "消费者准备消费");
Thread.sleep(100);
returnname;
}
publicvoidsetNameNull() {
name= null;
}
}
classProductApple implementsRunnable {
FriutPlate fp;
publicProductApple(FriutPlate fp) {
this.fp= fp;
}
@Override
publicvoidrun() {
try{
synchronized(fp) {
while(true) {
// System.out.println("正在往里放苹果");
fp.addFriut("苹果");
}
}
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
classProductOrange implementsRunnable {
FriutPlate fp;
publicProductOrange(FriutPlate fp) {
this.fp= fp;
}
@Override
publicvoidrun() {
try{
synchronized(fp) {
while(true) {
// System.out.println("正在往里放橘子");
fp.addFriut("橘子");
}
}
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
classConsumerApple implementsRunnable {
FriutPlate fp;
publicConsumerApple(FriutPlate fp) {
this.fp= fp;
}
@Override
publicvoidrun() {
while(true) {
synchronized(fp) {
String friutName= null;
try{
friutName= fp.getFriut();
} catch(InterruptedException e1) {
// TODOAuto-generated catch block
e1.printStackTrace();
}
if("苹果".equals(friutName)) {
System.out.println("儿子吃掉苹果");
fp.setNameNull();
} else{
System.out.println("不是苹果,儿子不吃");
try{
Thread.sleep(100);
} catch(InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
classConsumerOrange implementsRunnable {
FriutPlate fp;
publicConsumerOrange(FriutPlate fp) {
this.fp= fp;
}
@Override
publicvoidrun() {
while(true) {
synchronized(fp) {
String friutName= null;
try{
friutName= fp.getFriut();
} catch(InterruptedException e1) {
// TODOAuto-generated catch block
e1.printStackTrace();
}
if("橘子".equals(friutName)) {
System.out.println("女儿吃掉橘子");
fp.setNameNull();
} else{
System.out.println("不是橘子,女儿不吃");
try{
Thread.sleep(100);
} catch(InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
publicstaticvoidmain(String[] args) {
Demo d= newDemo();
FriutPlate fp= d.newFriutPlate();
ProductApple pa= d.newProductApple(fp);
ProductOrange po= d.newProductOrange(fp);
ConsumerApple ca= d.newConsumerApple(fp);
ConsumerOrange co= d.newConsumerOrange(fp);
Thread t1= newThread(pa);
Thread t2= newThread(po);
Thread t3= newThread(ca);
Thread t4= newThread(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)时,这种嵌套锁,一定会出现死锁
