使用ReentrantLock避免死锁(Avoiding deadlock using ReentrantLock)
我正在做一些练习作业,并涉及一些虚拟代码,试图更好地理解线程和锁的概念。 以下是一段代码(有时)陷入僵局。
A.java
public class A { private B b; public void setB(B b) { this.b = b; } public synchronized void foo(boolean callBar) { System.out.println("foo"); if (callBar) { b.bar(false); } } }
B.java
public class B { private A a; public void setA(A a) { this.a = a; } public synchronized void bar(boolean callFoo) { System.out.println("bar"); if (callFoo) { a.foo(false); } } }
Demo.java
public class Demo { public static void main(String[] args) { A a = new A(); B b = new B(); a.setB(b); b.setA(a); new Thread(() -> { a.foo(true); }).start(); new Thread(() -> { b.bar(true); }).start(); } }
解决方案 :我使用的是
Lock
而不是synchronized
。A.java
public class A { private final ReentrantLock lock = new ReentrantLock(); private B b; public void setB(B b) { this.b = b; } public ReentrantLock lock() { return lock; } public boolean impendingExecute() { Boolean thisLock = false; Boolean otherLock = false; try { thisLock = lock.tryLock(); otherLock = b.lock().tryLock(); } finally { if (!(thisLock && otherLock)) { if (thisLock) { lock.unlock(); } if (otherLock) { b.lock().unlock(); } } } return thisLock && otherLock; } public void foo(boolean callBar) { System.out.println("foo"); if (callBar && impendingExecute()) { try { b.bar(false); } finally { lock.unlock(); b.lock().unlock(); } } } }
B.java
public class B { private final ReentrantLock lock = new ReentrantLock(); private A a; public void setA(A a) { this.a = a; } public ReentrantLock lock() { return lock; } public boolean impendingExecute() { Boolean thisLock = false; Boolean otherLock = false; try { thisLock = lock.tryLock(); otherLock = a.lock().tryLock(); } finally { if (!(thisLock && otherLock)) { if (thisLock) { lock.unlock(); } if (otherLock) { a.lock().unlock(); } } } return thisLock && otherLock; } public void bar(boolean callFoo) { System.out.println("bar"); if (callFoo && impendingExecute()) { try { a.foo(false); } finally { lock.unlock(); a.lock().unlock(); } } } }
进行上述更改后,代码不会导致死锁。 这是实现它的正确方法(基本上,我希望审查
impendingExecute()
方法。)? 此外,(稍微偏离审查)是否有任何我可以遇到的真实场景?注意 :我在Code Review上发布了这个问题,但似乎对虚拟代码的审查是偏离主题的。
I was doing some practice assignments and dabbling around with some dummy code for trying to develop a better understanding of the concepts of threads and locks. Following is a piece of code that (sometimes) goes into deadlock.
A.java
public class A { private B b; public void setB(B b) { this.b = b; } public synchronized void foo(boolean callBar) { System.out.println("foo"); if (callBar) { b.bar(false); } } }
B.java
public class B { private A a; public void setA(A a) { this.a = a; } public synchronized void bar(boolean callFoo) { System.out.println("bar"); if (callFoo) { a.foo(false); } } }
Demo.java
public class Demo { public static void main(String[] args) { A a = new A(); B b = new B(); a.setB(b); b.setA(a); new Thread(() -> { a.foo(true); }).start(); new Thread(() -> { b.bar(true); }).start(); } }
Solution: I used
Lock
s instead ofsynchronized
.A.java
public class A { private final ReentrantLock lock = new ReentrantLock(); private B b; public void setB(B b) { this.b = b; } public ReentrantLock lock() { return lock; } public boolean impendingExecute() { Boolean thisLock = false; Boolean otherLock = false; try { thisLock = lock.tryLock(); otherLock = b.lock().tryLock(); } finally { if (!(thisLock && otherLock)) { if (thisLock) { lock.unlock(); } if (otherLock) { b.lock().unlock(); } } } return thisLock && otherLock; } public void foo(boolean callBar) { System.out.println("foo"); if (callBar && impendingExecute()) { try { b.bar(false); } finally { lock.unlock(); b.lock().unlock(); } } } }
B.java
public class B { private final ReentrantLock lock = new ReentrantLock(); private A a; public void setA(A a) { this.a = a; } public ReentrantLock lock() { return lock; } public boolean impendingExecute() { Boolean thisLock = false; Boolean otherLock = false; try { thisLock = lock.tryLock(); otherLock = a.lock().tryLock(); } finally { if (!(thisLock && otherLock)) { if (thisLock) { lock.unlock(); } if (otherLock) { a.lock().unlock(); } } } return thisLock && otherLock; } public void bar(boolean callFoo) { System.out.println("bar"); if (callFoo && impendingExecute()) { try { a.foo(false); } finally { lock.unlock(); a.lock().unlock(); } } } }
After making the above changes, the code doesn't lead to a deadlock. Is it the proper way to implement this (Basically, I want the
impendingExecute()
method to be reviewed.)? Also, (deviating a bit from the review) are there any real world scenarios I can encounter this?Note: I had posted this question on Code Review but it seems reviewal of dummy code is off-topic.
原文:https://stackoverflow.com/questions/44094584
最满意答案
除非您想为每种情况手动重置边距/填充,否则不应将容器类添加到将作为全宽的父div。
基本上,div的层次结构是
div.container > div.row > div.col-xs-12/ div.col-md-6
(etc ..)..如果你想要一个全宽度的容器,例如:
div.conainer-fluid > div.container > div.row > div.col-md-6
(etc ..)。the container class shouldn't be added to a parent div that is going to be full width unless you want to manually reset the margin/padding for each situation.
basically, the hierarchy of divs goes
div.container > div.row > div.col-xs-12/ div.col-md-6
(etc..) ..if you want a full width container eg:
div.conainer-fluid > div.container > div.row > div.col-md-6
(etc..).
相关问答
更多-
不,你只需要col-xs-12。 除非进行新的列分配,否则最小屏幕的列分配适用于所有较大的设备。 No, you just need col-xs-12. The column allocation for the smallest screen applies to all larger devices unless a new column allocation is made.
-
您应该删除col-md-4和col-md-8以获得全宽查看下面的代码 $(document).ready(function() { $(".cssCircle").click(function() { var id = $(this).attr('data-target'); $(id).show(); }); });您的图片无法填充整个元素的原因是因为您使用background-size:contain; 。 这样,通过调整图像大小以适合高度或宽度,图像将包含在该元素内。 如果一个尺寸小于另一个,那就这样吧。 图像将变得足够高以适合元素,或者在您的情况下,足够宽以适应元素,同时保持相同的宽高比。 这也是您的图像在缩放时不调整大小的原因。 该元素的宽度也是浏览器的宽度。 因此,contains保持图像宽度与元素宽度相同,即元素宽度是浏览器的宽度。 The reason your image won't fill the ...你可以尝试用auto代替100% 喜欢这个: .band { width: auto !important; background-color: #D7EAD8; color: #323F3F; } You could try just replacing the 100% with auto like this: .band { width: auto !important; background-color: #D7EAD8; color: #323F3F; }2解决方案IMHO: 加入.row .row { margin: auto; } 集中你的块(见https://jsfiddle.net/os7frkq5/1/ ) 或者只是删除width: 100% :参见https://jsfiddle.net/os7frkq5/2/ ) 2 solutions IMHO : Add in .row .row { margin: auto; } to center your block (see https://jsfiddle.net/os7frkq5 ...
bootstrap,我无法让容器变得流畅(全宽)col-md-12(bootstrap, I cannot get the container to be fluid (full width) col-md-12)[2023-01-01]
除非您想为每种情况手动重置边距/填充,否则不应将容器类添加到将作为全宽的父div。 这就是我想你想要的 这里的工作代码最少 基本上,div的层次结构是div.container > div.row > div.col-xs-12/ div.col-md-6 (etc ..).. 如果你想要一个全宽度的容器,例如: div.conainer-fluid > div.container > div.row > div.col-md-6 (etc ..)。 the container class shouldn' ...你有几个拼写错误,并且没有针对正确的div,请参阅小提琴: https : //jsfiddle.net/c259LrpL/9/ set4需要是.set4 ,因为你想在set4列中定位div col-md-12 ,你应该使用下面的css。 .set4 > .row > .col-md-12{ background-color: black; height: 250px; } You have a couple typo's and where not targeting the corre ...这不是因为容器流体,而是你的行元素的边距为15px。 您的codepen已更新 只需添加 .row { margin-right: 0px; } .row { margin-right: 0px; }