Synchronized 同步方法和同步代码块

来源:互联网 发布:宝冢96期事件 知乎 编辑:程序博客网 时间:2024/05/17 20:12
    * 同步代码块语法:
     * synchronized(受益对象){代码块}
     * 同步方法同同步代码块的区别
     * 1.同步方法,是通过this关键字找到当前对象,将当前对象上锁
     * 2.同步代码块,可以指定任意一个对象
     * 同步代码块,可以控制的更具体

(另一个地方看的和上面的是一个意思的:java中每个对象都有同步锁,同步方法是指进入该方法时需要获取this对象的同步锁,而同步代码块则是可以指定需要获取哪个对象的同步锁,以下代码实际上一个效果:
synchronized void t(){}
void t(){
 synchronized(this){
 }
}
同步代码块可以用如下方式来使用:
void t(){
 synchronized(lockObject){}
}
其中lockObject可以为任何不为null值的对象)




Java代码  
  1. public class Foo implements Runnable{  
  2.     private static byte[] lock new byte[0];  
  3.       
  4.     @Override  
  5.     public void run()  
  6.           
  7.     methodA();  
  8.                       
  9.      
  10.   
  11.     public synchronized void methodA(){  
  12.         System.out.println(this);  
  13.      
  14.       
  15.     public void methodB(){  
  16.         synchronized(this){  
  17.             System.out.println(this);  
  18.          
  19.      
  20.       
  21.     public void methodC(){  
  22.         synchronized(lock){  
  23.             System.out.println(lock);  
  24.          
  25.      
  26.  

 

Java代码  
  1. public class ThreadTest  
  2.     public static void main(String[] args)  
  3.         Foo f1=new  Foo();  
  4.         Foo f2=new  Foo();  
  5.         new Thread(f1).start();  
  6.         new Thread(f2).start();  
  7.      
  8.   
  9.  

 

 

 

无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――同步方法很可能还会被其他线程的对象访问

看 methodA:

这时synchronized锁定的是哪个对象呢?它锁定的是调用这个同步方法对象。也就是说,当一个对象f1在不同的线程中执行这个同步方法时,它们之间会形成互斥(f1的一个线程执行完这个方法,另一个f1的线程再执行这个方法),达到同步的效果。如下面的两行代码:

new Thread(f1).start();

new Thread(f1).start();

 

但是这个对象所属的Class所产生的另一对象f2却可以任意调用这个被加了synchronized关键字的方法。

new Thread(f1).start();

new Thread(f2).start();

f1  f2 可以同时访问方法。这样达不到同步的效果

MethodA和methodB的效果是一样的。

如果要保持即使不同对象也只能有一个线程来访问可以创建一个特殊的instance变量(它得是一个对象)来充当锁

(用byte数组对象比Object Object lock = new Object() 高效  注意这个得是static的,让不同对象竞争同一个 byte数组对象的锁)

 

像method3 这样,谁拿到这个锁谁就可以运行它所控制的那段代码