java多线程嵌套_Java多线程进阶

7780bc1b43f58837494f7f40f4465bba.png

c4f48bc249013da72c80d2049fd6f066.png

需要理解锁是什么意思?

首先是发生在多线程的情况下;

线程a,线程b,共享资源share

例如,share的资源一次只能被一个对象操作,这时候需要一个东西来标识(也叫监视器)出来表明该资源已经有人(指的是线程)在使用了,请还要使用的人(指的是线程)进入等待(线程等待池/队列);

怎么实现呢?

synchronized关键字,配合一个唯一的东西,可以是类.class,也可以是对象本身;但注意的是必须是一个引用的数据类型,如包装类,obj等

1.生产者和消费者模式

8215c67df9f45415fc284d064e5d0485.png

代码演示:

a33a72318ff1f7017abb2e2550019040.png

cae0a1c4cb598e81648b7e4ca0d84384.png

763e983bd5402d610d3cd94e3e03f087.png

3f34abf7be9d3e1f200729c1ac883dca.png

99854887a1bf6c972ae65a139d9b9bbb.png

重点练习1:

e834153e56a4f131bc348437dd4d9a2e.png

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

e0d20501682862fcaba5b344e219892b.png

b12dbcd44e4b8e7091c9f6df73936a6a.png

90d6701dc3e933b8fbe5e5ded07d5d11.png

43bdcfd5935f4e3c8c3a793ec39e763c.png

0b3f627c203c1c2d3b612f37c58c7d20.png

a219bd69da888523e5adea57a75b5bc5.png

7cd846d3e0a3c15e810a103c43a0fbb9.png

44f0cdfc5debd34de0027b6919032b93.png

重点练习2:

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

f32f4fda0b9d2a4f46455936741ed681.png

13a997e7016af799bf4ae0dee6a50e2a.png

39bb3b671338de510e601895645ae80a.png

4f2e0071ab457c06643aec6c66a39963.png

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)时,这种嵌套锁,一定会出现死锁

594f4857807cab23a5d5e3a817bc0030.png


版权声明:本文为weixin_36002897原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。