java同步synchronized详解

       synchronized能够修饰代码块也能够修饰方法,还能够做用于静态方法,类和某个实例java

       每一个对象都有一把锁,当多个线程同时访问共享资源的时候,须要用到synchronized,synchronized分为代码块和方法,代码块须要显示的指定对象,而方法不须要(即当前对象)。ide

        java的内存模型是对每个进程都有主内存,每一个线程也有本身的内存,它们从主内存中取数据,而后在计算,在存入主内存。函数

         例子:如今有两个线程A,B线程,A线程对变量i加1,B线程同时对i加2,这两个线程同时操做,若是没有同步处理则B线程作的操做会覆盖A线程的操做。this

         这时能够用synchronized处理,synchronized具备原子性,原子操做:取数据,操做数据,存数据。synchronized能够保证同一时间只有一个线程操做该对象。spa

        java中对非Long和Float原始数据类型的存,取为原子操做。其实就是对一个字节的存,取操做,因为Float和Long为两个字节,因此其取,存为非原子操做。若是想把他们变成原子操做能够用volatile.线程

        做用区域主要有两种:code

        (1)、方法对象

        (2)、代码块进程

          对于用一对像的同步操做只能有一个线程,而对于不一样对象是互不干扰的。
内存

  Public synchronized void change() {
     //同步方法
  }
  Public void change() { 
      Synchronized(this) {
          //同步语句:(由于效率问题,有时考虑使用同步语句块)
      }
   }

   同步方法是针对当前对象的,若是不针对当前对象,而是针对其余对象能够用同步语句,如:

private byte[]  lock= new byte[0];
 
  Public void change() {
    Synchronized(lock) {
  }
}

自定义锁注意:

   a、对象必须为private防止其余类对象访问

   b、geter方法最好clone一个对象返回

其余用法

      能够针对静态方法和类

Class Foo   {   
public synchronizedstatic void methodAAA()// 同步的static 函数  
{   
//….  
}  
  public void methodBBB()   {   
       synchronized(Foo.class)
             // class literal(类名称字面常量) 
 } 
}

  它是针对整个类的,因此只能是同一个类的一个线程进行访问

  synchronized(this)与synchronized(static class)的区别:

     synchronized就是针对内存区块申请内存锁,this是类的一个对象,也就是针对相同对象的互斥操做,其余线程能够访问该类的其余对象。static是针对类,static是整个类共有的,也就是该类的全部成员间互斥。在同一时间只有一个线程能够访问该类的实例。

创建三个线程,A线程打印10次A,B线程打印10次B,C线程打印10次C,要求线程同时运行,交替打印10次ABC。这个问题用Object的wait(),notify()就能够很方便的解决。代码以下:

public class MyThreadPrinter2 implements Runnable {     
    
    private String name;     
    private Object prev;     
    private Object self;     
    
    private MyThreadPrinter2(String name, Object prev, Object self) {     
        this.name = name;     
        this.prev = prev;     
        this.self = self;     
    }     
    
    @Override    
    public void run() {     
        int count = 10;     
        while (count > 0) {     
            synchronized (prev) {     
                synchronized (self) {     
                    System.out.print(name);     
                    count--;    
                      
                    self.notify();     
                }     
                try {     
                    prev.wait();     
                } catch (InterruptedException e) {     
                    e.printStackTrace();     
                }     
            }     
    
        }     
    }     
    
    public static void main(String[] args) throws Exception {     
        Object a = new Object();     
        Object b = new Object();     
        Object c = new Object();     
        MyThreadPrinter2 pa = new MyThreadPrinter2("A", c, a);     
        MyThreadPrinter2 pb = new MyThreadPrinter2("B", a, b);     
        MyThreadPrinter2 pc = new MyThreadPrinter2("C", b, c);     
             
             
        new Thread(pa).start();  
        new Thread(pb).start();  
        new Thread(pc).start();    }     
}
相关文章
相关标签/搜索