在LINUX中,使用spin_lock/spin_unlock来实现锁,调用时,都有一个锁名,例如spin_lock(&lock)/spin_unlock(&unlock)。
但是,在JAVA中,使用synchronized时,例如:
public synchronized read(int Length)
{
......
}
public synchronized write(char c)
{
......
}
并没有显式地指定锁名,系统怎么能判断在read时不能write呢?或者就是简单的将其处理成原子操作?如果我有两个缓冲区,都有read/write操作,这时的代码应该怎么实现呢?我对JAVA的同步不是很懂,哪位能详细的解说一下?
但是,在JAVA中,使用synchronized时,例如:
public synchronized read(int Length)
{
......
}
public synchronized write(char c)
{
......
}
并没有显式地指定锁名,系统怎么能判断在read时不能write呢?或者就是简单的将其处理成原子操作?如果我有两个缓冲区,都有read/write操作,这时的代码应该怎么实现呢?我对JAVA的同步不是很懂,哪位能详细的解说一下?
public synchronized void read1(int len)
public synchronized void write1(char c)
public synchronized void read2(int len)
public synchronized void write2(char c)
实际上,要求的是在read1时,不能执行write1,但是可以执行write2,那系统怎么区分呢?
private Object lock1 = new Object();
private Object lock2 = new Object();
public void read1(int len) {
synchronized(lock1) {
....
}
}
public void write(char ch) {
synchronized(lock1) {
....
}
}
public void read2(int len) {
synchronized(lock2) {
....
}
}
public void write2(char ch) {
synchronized(lock2) {
....
}
}这样就没有问题
在进行多线程编程时,经常要使用同步互斥机构,但java本身没有提供的同步互斥机构,仅提供了两个与同步互斥有关的方法:wait()和notify(),可以用来设计信号量类:mySemaphore,它是按照Dijkstra提出的计数信号量的思想设计的。 mySemaphore有两个最重要的成员方法:P()和V()。这两个方法实际就实现了信号量的P操作和V操作。具体描述如下: public synchronized void P(){ semaphore--; if(semaphore<0){ try{ wait(); }catch(InterruptedException ie){} } } public synchronized void V(){ semaphore++; if(semaphore<=0) notify(); } 其中,semaphore变量记录了信号量的状态,wait()方法相当于block原语,用于阻塞线程的执行,notify()方法相当于wakeup原语,用于唤醒线程恢复运行。由于这两个方法定义为synchronized,这样java虚拟机可保证这两个方法的原子执行,从而实现了P、V操作。
如果我需要两个信号量,例如:static mySem sem1;
static mySem sem2;
public void init()
{
sem1 = new mySem();
sem2 = new mySem();
}
class mySem
{
int semaphore;
public mySem()
{
semaphore=0;
}
public syncronized void P()
{
semaphore--;
if(semaphore<0)
{
try
{
wait();
}catch(InterruptedException ie){}
}
}
public synchronized void V()
{
semaphore++;
if(semaphore<=0)
notify();
}
}
在使用的时候,就会出问题?是否需要将其改为notifyAll
thread2:sem2.P()
thread2:sem2.V()这个时候,不是出问题了吗?如果notify唤醒的是随机的(或者唤醒的是第一个等待的进程),很可能唤醒thread1啊,thread2不是一直就挂起了吗?这时候,thread1实际上应该等待,而不是被唤醒啊!!!
另外一个问题,sem2.V()不可能在thread2中执行的,应该是thread3
mySem实例化为sem1和sem2后,sem1的notify,只会唤醒所有使用sem1.P()的进程?
这种机制是怎么实现的,通过this?
没有JAVA的源码,郁闷。
Read the ****ing sources!!!
因为sem1,sem2已经是两个不同的信号量了。上面这些当然是JVM已经实现好了,没有看过JVM实现的源代码
呵呵,我可是第一次拿分啊。
synchronized(obj)
{
...
}
第二种就是搂主提到的,在方法前加synchronized关键字。
第三种是static方法前加synchronized关键字。第一种用法是对对象obj加锁,
第二种是对this对象加锁,
第三种是对改类的一个隐藏的成员变量加锁,这个变量是ClassName.class,Java里每一个类都有一个这样的变量,变量名都是class,比如:
class Test
{
static void synchronized method(){};
}
等同于:
class Test
{
static void synchronized method()
{
synchronized (Test.class)
{
}
};
}