让“res”程序中有一个共享资源。假设有两个线程想要进入临界区:
void Meth(...){
... //Что нужно написать, чтобы на консоль вывелось сообщение, что тред (threadName) ждёт, когда
synchronized (res)//Здесь разделяемый ресурс
{
//some code
}
}
我是这样实现的,一切正常(恕我直言),但我有很大的疑问:
Class Resource {
boolean isBusy = false; //Флаг который бы переключался, если объект ресурса захватывался.
}
class A extend Thread{
String name;
static Resource res = new Resource(); //Создал объект ресурса
void Meth() throws InterruptedException {
try{
while(res.isBusy==true){
System.out.println("Потоку " + this.name + " приходится подождать.");
Thread.currentThread().sleep(7);
}
synchronized (res)//Здесь разделяемый ресурс
{
res.isBusy = true;
... //some code
res.isBusy = false;
}
catch (Exception e){ e.printStackTrace();}
}
}
如果十几个线程周期性地等待直到关键部分被释放,并且在等待的过程中它们必须通知程序员他们正在等待,这样的实现是否正常?我怀疑正确性,因为我正在轮询一个繁忙的对象,试图读取它的字段。所以你绝对可以做到而不用担心程序会崩溃?
java中是否有任何其他普遍接受的实现显示线程无法进入同步块的消息,因为它正在等待释放?
如果需要直接上报,那么“临界区”可以不用包裹
synchronized
,而是包裹在但总的来说,
res.isBusy = true;
这种方法显然不是来自java,所以如果问题更具体,它可以做得更好,无论是代码可读性和可维护性,还是性能方面。在 java 中,有很多方法可以在没有锁的情况下读取和更改对象的字段。不,因为通常它们要么不这样做(它们阻止较小的操作,因此线程不会相互等待);或者,如果根据任务的含义,他们必须等待很长时间,那么重新组织使用该资源的工作可能是有意义的(例如,控制线程在没有同步的情况下使用该资源,并将任务分散到其他线程,它们并行工作而不会阻塞资源)
首先,您的代码的缺点
isBusy
必须声明为volatile
否则,在块外读取该字段的值时synchronized
,可能会读取到错误的值isBusy
在您检查标志之后但在进入该部分之前,另一个线程有可能会获取资源synchronized
所有这些问题都通过用
synchronized
对象替换部分来解决ReentrantLock