Fist of all, java intrinsic locks are reentrant. It means that thread that already holds a lock can acquire the same lock. Without that property the thread would block when reacquiring the lock it already holds. POSIX locks ( or mutex variables) are not reentrant (of recursive) by default but can become reentant if properly configured.
I can illustrate that with the following example: the thread-safe class that allows setting x, y and both coordinates at the same time. Note, that this is just the example and real-time implementation would greatly differ.
// Point.java
public class Point {
private int x = 0;
private int y = 0;
public synchronized void setValue(int x, int y) {
setX(x);
setY(y);
}
public synchronized void setX(int x) {
this.x = x;
}
public synchronized void setY(int y) {
this.y = y;
}
public static void main(String[] args) {
Point p = new Point();
p.setValue(3, 5);
}
}
setValue
proceeds without any problems. But the similar example using POSIX threads will block if not configured in a special way:// point.cppTo achieve reentrancy with POSIX threads one can initialise the mutex (or lock) as follows:
#include <pthread.h>
class Point
{
public:
Point();
virtual ~Point();
void setX(int x);
void setY(int y);
void setValue(int x, int y);
private:
int _x;
int _y;
pthread_mutex_t _lock;
};
Point::Point() : _x(0), _y(0)
{
// initialize mutex lock
pthread_mutex_init(&_lock, NULL);
}
Point::~Point()
{
// destroy mutex lock
pthread_mutex_destroy(&_lock);
}
void Point::setX(int x)
{
if (pthread_mutex_lock(&_lock))
return;
_x = x;
pthread_mutex_unlock(&_lock);
}
void Point::setY(int y)
{
if (pthread_mutex_lock(&_lock))
return;
_y = y;
pthread_mutex_unlock(&_lock);
}
void Point::setValue(int x, int y)
{
if (pthread_mutex_lock(&_lock))
return;
setX(x);
setY(y);
pthread_mutex_unlock(&_lock);
}
int main()
{
Point p;
p.setValue(3, 5);
}
Point::Point() : _x(0), _y(0)
{
// initialize mutex lock
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&_lock, &attr);
}
No comments:
Post a Comment