还可以作用于静态方法,类和某个实例。

synchronized分为代码块和方法,代码块需要显示的指定对象,而方法不需要(即当前对象)。

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

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

synchronized具有原子性,原子操作:取数据,操作数据,存数据。synchronized可以保证同一时间只有一个线程操作该对象。

java中对非Long和Float原始数据类型的存,取为原子操作。其实就是对一个字节的存,取操作,由于Float和Long为两个字节,所以其取,存为非原子操作。如果想把他们变成原子操作可以用volatile.

        作用区域主要有两种:

        (1)、方法

        (2)、代码块

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

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

   同步方法是针对当前对象的,如果不针对当前对象,而是针对其他对象可以用同步语句,如:

private byte[]  lock= new byte[0];
 
  Public void change() {
    Synchronized(lock) {
  }
}
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(类名称字面常量) 
 } 
}
Class Foo   {   
public synchronizedstatic void methodAAA()// 同步的static 函数  
{   
//….  
}  
  public void methodBBB()   {   
       synchronized(Foo.class)
             // class literal(类名称字面常量) 
 } 
}

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

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();    }     
}
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();    }     
}