当多个线程同时访问一个资源时,非常容易出现安全问题。因此需要采用同步机制来解决这种问题。Java主要提供了3种实现同步机制的方法:

1)、synchronized关键字

synchronized有两种用法(synchronized方法和synchronized块)

synchronized方法。在方法的生命前加入synchronized关键字,示例如下:

public synchronized void mutithreadAccess();

synchronized块:synchronized块既可以把任意的代码声明为synchronized,也可以指定上锁的对象。有非常高的灵活性,代码如下:

synchronized(syncObject){代码块}

2)、wait()方法和notify()方法:

当使用synchronized来修饰某个共享资源时,如果线程A1执行synchronized代码,另外一个线程A2也要同时执行同一对象的同一synchronized代码时,线程A2将要等到线程A1执行完后,才能继续执行。这种情况下可以使用wait()方法和notify()方法。

在synchronized代码被执行期间,线程可以调用对象的wait方法,释放对象锁,进入等待状态,并且可以调用notify()方法或notify()方法通知正在等待的其他线程。notify()方法仅唤醒一个线程(等待队列中的第一个线程)并允许它去获得锁,notifyAll()方法唤醒所有等待这个对象的线程并允许它们去获得锁。

 

3)、Lock

JDK5新增了Lock接口以及它的一个实现类ReentrantLock(重入锁),Lock也可以用来实现多线程同步。

 

[html] view plain copy

 

    1. import java.util.concurrent.locks.*;  
    2. class Resource  
    3. {  
    4.     private String name;  
    5. count=1;  
    6. flag=false;  
    7. lock=new ReentrantLock();  
    8.   
    9. condition_pro=lock.newCondition();  
    10. condition_con=lock.newCondition();  
    11.     public void set(String name)  throws InterruptedException  
    12.     {  
    13.         lock.lock();  
    14.         try  
    15.         {  
    16.             while(flag)  
    17.                 condition_pro.await();  
    18. this.name=name+"-----"+count++;  
    19.             System.out.println(Thread.currentThread().getName()+"------生产者-------"+this.name);  
    20. flag=true;  
    21.             condition_con.signal();  
    22.         }  
    23.         finally  
    24.         {  
    25.             lock.unlock();  
    26.         }  
    27.     }  
    28.     public  void out() throws InterruptedException  
    29.     {  
    30.         lock.lock();  
    31.         try  
    32.         {  
    33.             while(!flag)  
    34.                 condition_con.await();  
    35.             System.out.println(Thread.currentThread().getName()+"--消费者--"+this.name);  
    36. flag=false;  
    37.             condition_pro.signal();  
    38.         }  
    39.         finally  
    40.         {  
    41.             lock.unlock();  
    42.         }     
    43.     }  
    44. }  
    45. class Producer implements Runnable  
    46. {  
    47.     private Resource res;  
    48.     Producer(Resource res)  
    49.     {  
    50. this.res=res;  
    51.     }  
    52.     public void run()  
    53.     {  
    54.         while(true)  
    55.         {  
    56.             try  
    57.             {  
    58.                 res.set("++面包++");  
    59.             }  
    60.             catch (InterruptedException e)  
    61.             {  
    62.             }  
    63.               
    64.         }  
    65.     }  
    66. }  
    67. class Consumer implements Runnable  
    68. {  
    69.     private Resource res;  
    70.     Consumer(Resource res)  
    71.     {  
    72. this.res=res;  
    73.     }  
    74.     public void run()  
    75.     {  
    76.         while(true)  
    77.         {  
    78.             try  
    79.             {  
    80.                 res.out();  
    81.             }  
    82.             catch (InterruptedException e)  
    83.             {  
    84.             }  
    85.         }  
    86.     }  
    87. }  
    88. class ProducerConsumerDemo2   
    89. {  
    90.     public static void main(String[] args)   
    91.     {  
    92. res=new Resource();  
    93.           
    94. pro=new Producer(res);  
    95. con=new Consumer(res);  
    96.           
    97. t1=new Thread(pro);  
    98. t2=new Thread(pro);  
    99. t3=new Thread(con);  
    100. t4=new Thread(con);  
    101.           
    102.         t1.start();  
    103.         t2.start();  
    104.         t3.start();  
    105.         t4.start();  
    106.     }  
    107. }  
    108.