java的同步块

Java的同步块标志了一个方法或者代码块是同步的。Java的同步块可以用来避免竞争条件

Java的同步关键字

Java中的同步块是使用synchronized关键字标注的。Java中的同步块是在对象上同步的。所有在这些同时只能有一个线程在上边执行。其他线程想进入这个同步块只能等到同步块中的线程退出才可以。
synchronized 关键字有四种标示的类型
1、实例方法
2、静态方法
3、实例方法中的代码块
4、静态方法中的代码块

同步实例方法

下边是一个同步的实例方法
  public synchronized void add(int value){
      this.count += value;
  }

注意在方法的声明上使用synchronized 关键字,这告诉Java这个方法是同步的。Java中的一个同步的实例方法是在实例(对象)方法上的同步。因此,每一个实例在不同的对象上有它自己的同步方法:自己的实例。只有一个线程能够在实例方法中执行,如果存在多个线程,那么一个线程只能在一个同步实例方法中执行,一个线程一个实例。

同步静态方法

静态方法标注就像实例方法一样也是使用synchronized 关键字,下边是一个Java同步静态方法的例子
  public static synchronized void add(int value){
      count += value;
  }

synchronized 关键字告诉Java这个方法是同步的。同步静态方法是在类的静态方法上的同步。因为只有一个类对象存在于JVM中,只有一个线程能够在静态的同步方法中执行。如果静态同步方法在不同的类中,那么一个线程可以在每一个静态的方法中执行静态同步方法。一个线程一个类。

实例方法中的同步块

你不必同步整个方法,有时同步方法的某一个部分会更好,在方法中使用同步代码块可以解决这个问题。下边是在没有同步的方法中使用同步代码块的代码
  public void add(int value){

    synchronized(this){
       this.count += value;   
    }
  }

这个例子使用了Java的同步块来标志一段代码是同步的,这段代码可以被当做它是一个同步方法一样执行。注意Java同步代码块的构建是在括号中当做一个对象。在这个方法中使用“this”,也就是实例增加的调用的方法。括号中同步构建的对象叫做微小对象,这段代码被认为是在微小对象上的同步,同步实例上使用的这个对象被认为是微小对象。只有一个线程可以在微小对象内运行。下边是两个方法的使用,实际上他们是等同的。
  public class MyClass {
  
    public synchronized void log1(String msg1, String msg2){
       log.writeln(msg1);
       log.writeln(msg2);
    }

  
    public void log2(String msg1, String msg2){
       synchronized(this){
          log.writeln(msg1);
          log.writeln(msg2);
       }
    }
  }

在这个例子中只有一个线程能够在上边这两个方法中的其中一个里边运行。

Java同步例子

下边这个例子开启了两个线程,在同一个实例上调用了add方法,同时只能有一个在这个实例上调用这个方法,因为在这个实例上,这个方法是同步的。
  public class Counter{
     
     long count = 0;
    
     public synchronized void add(long value){
       this.count += value;
     }
  }

  public class CounterThread extends Thread{

     protected Counter counter = null;

     public CounterThread(Counter counter){
        this.counter = counter;
     }

     public void run() {
	for(int i=0; i<10; i++){
           counter.add(i);
        }
     }
  }

  public class Example {

    public static void main(String[] args){
      Counter counter = new Counter();
      Thread  threadA = new CounterThread(counter);
      Thread  threadB = new CounterThread(counter);

      threadA.start();
      threadB.start(); 
    }
  }

创建了两个线程,同一个实例Counter在他们的构造函数中传递给他们,这个Counter.add方法在实例上是同步的,因为这个add方法是实例的方法并且是同步的方法,因此同时只能有一个线程调用这个方法,其他的线程只能等待这个方法直到这个线程离开这个方法。如果两个线程引用了两个不同的Counter实例,同时调用add方法将会没有任何问题,调用时发生在不同的对象上的,方法的调用当然是同步的,因此调用不会被阻塞。
  public class Example {

    public static void main(String[] args){
      Counter counterA = new Counter();
      Counter counterB = new Counter();
      Thread  threadA = new CounterThread(counterA);
      Thread  threadB = new CounterThread(counterB);

      threadA.start();
      threadB.start(); 
    }
  }

Java的并发措施

这个Java的synchronized机制是Java的第一种在多线程下访问对象的同步机制,这个synchronized 机制并不是很先进。这就是为什么Java5有了一系列的并发类来帮助开发人员获取更好的并发控制。

原文地址:http://tutorials.jenkov.com/java-concurrency/synchronized.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值