在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的同步不是很懂,哪位能详细的解说一下?

解决方案 »

  1.   

    我的意思是:
       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,那系统怎么区分呢?
      

  2.   

    那么你不应该在方法上声明synchronized ,在方法上声明 synchronized表示进入这个方法必须对这个对象加锁你可以这样
    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) {
        ....
      }
    }这样就没有问题
      

  3.   

    hehe,实际上,我把同步和互斥混淆了,synchronized是同步机制,我需要的是互斥机制,参考http://fanqiang.chinaunix.net/program/java/2001-06-08/2098.shtml:
    在进行多线程编程时,经常要使用同步互斥机构,但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操作。
      

  4.   

    同意楼上,syncronized是对对象进行同步.
      

  5.   

    还有一个问题,就是上面的P/V操作中,调用notify();系统根据什么来判断这时候唤醒的是哪一个的wait()???
      

  6.   

    那是否意味着:
    如果我需要两个信号量,例如: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
      

  7.   

    我一般会使用notifyAll多点,只是在p中要用while而不是if来判断另外,上面的问题不会出问题啊,系统是随机唤醒一个正在等这个对象的线程,当时不是所有等待线程
      

  8.   

    thread1:sem1.P()
    thread2:sem2.P()
    thread2:sem2.V()这个时候,不是出问题了吗?如果notify唤醒的是随机的(或者唤醒的是第一个等待的进程),很可能唤醒thread1啊,thread2不是一直就挂起了吗?这时候,thread1实际上应该等待,而不是被唤醒啊!!!
      

  9.   

    你要注意,我说的是同一个对象,而不是同一个类!!!!!!!sem1和sem2根本不是同一个对象,所以系统不会唤醒thread1
    另外一个问题,sem2.V()不可能在thread2中执行的,应该是thread3
      

  10.   

    你的意思是:
    mySem实例化为sem1和sem2后,sem1的notify,只会唤醒所有使用sem1.P()的进程?
    这种机制是怎么实现的,通过this?
    没有JAVA的源码,郁闷。
    Read the ****ing sources!!!
      

  11.   

    这个是当然的,sem1.nofity只可能唤醒sem1.P,这个是PV的最最基本的要求了吧。
    因为sem1,sem2已经是两个不同的信号量了。上面这些当然是JVM已经实现好了,没有看过JVM实现的源代码
      

  12.   

    看来问题基本有个说法了,怎么给分呢?给自己10,给ChDw(米)10?
    呵呵,我可是第一次拿分啊。
      

  13.   

    解决办法ChDw(米)已经说了,我说说synchronized原理Java里synchronized有三种用法,第一种是:
    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)
        {
        }
      };
    }