【发布时间】:2013-11-17 20:32:55
【问题描述】:
我自己正在做这个小练习,试图了解我应该如何使用并发和线程。
有时我有一个我不能修改它的源代码并且不是线程安全的对象,所以我希望它只被一个线程访问。
在此示例中,我无法触摸的第三方对象称为 Holdeable。我所做的是尝试将它包装到一个名为 Holder 的类中,该类具有同步方法,并且我希望通过这样做只有一个线程可以访问该 Holdeable 对象。有时我将对 Holdeable 对象的引用设置为空,并且我希望它正确地完成,以便当其他线程评估 mHolder.getHoldeable()==null 为真时,并避免输入可能导致 NullPointerException 的代码。
我的最后一次尝试包括一个同步块,是这样的:
class Holder {
Holdeable mHoldeable;
public synchronized void setHoldeable(Holdeable holdeable) { mHoldeable = holdeable; }
public synchronized Holdeable getHoldeable() { return mHoldeable; }
}
class Holdeable { // Cannot be modified, that would be to cheat :D
public int someValue;
}
public class MainClass {
private static Holder mHolder;
public static void main(String[] args) {
try {
Holdeable holdeable = new Holdeable();
mHolder = new Holder();
mHolder.setHoldeable(holdeable);
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true) {
synchronized(mHolder) {
if(mHolder.getHoldeable() != null) {
Thread.sleep(23);
System.out.println(mHolder.getHoldeable().someValue);
} else {
System.out.println("No holder!");
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(1000);
mHolder.getHoldeable().someValue = 2;
Thread.sleep(1500);
mHolder.getHoldeable().someValue = 3;
Thread.sleep(500);
mHolder.setHoldeable(null);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
此示例避免抛出 NullPointerException,但正如您所见,执行如此多的锁定只需要很多时间。当我阅读“并发的艺术”一书时,我正在努力解决这个问题,看看我是否终于明白了。
你怎么看?
【问题讨论】:
标签: java multithreading concurrency