文档章节

java 同步块(Java Synchronized Blocks)

丁佳辉
 丁佳辉
发布于 2015/08/18 13:31
字数 958
阅读 106
收藏 1

Java 同步块包括方法同步和代码块同步。java 同步可以避免资源竞争,避免死锁。

主题包括的主要内容:

The Java synchronized Keyword

在java中,同步是用 synchronized 关键字代表的. 同步是针对对象和类来说的。一个对象上的所有同步块只能被一个线程锁住。其他所有的线程试图访问同步块的方法,都要等到占用资源的线程释放了才能访问。

synchronized关键字可以用到4个种场景:

  1. Instance methods

  2. Static methods

  3. Code blocks inside instance methods

  4. Code blocks inside static methods

Synchronized Instance Methods

Here is a synchronized instance method:

  public synchronized void add(int value){
      this.count += value;
  }

当一个方法上用到synchronized关键字,Java才能知道它是个同步方法。

一个实例同步方法只属于实例本身。每个实例都有自己的同步方法。

Synchronized Static Methods

Static methods are marked as synchronized just like instance methods using thesynchronized keyword. Here is a Java synchronized static method example:

  public static synchronized void add(int value){
      count += value;
  }

同样 synchronized 告诉Java 这是一个同步方法。

同步静态方法属于类对象。在VM中只有一个类对象,因此只能有一个线程执行静态同步方法。

Synchronized Blocks in Instance Methods

有时候, 不需要同步整个方法,只需要同步方法里面的一部分,可以借助同步块来完成工作。

Here is a synchronized block of Java code inside an unsynchronized Java method:

  public void add(int value){    synchronized(this){
       this.count += value;   
    }
  }

这个例子是用同步块标记一块同步代码。这个同步块代码就相当于同步方法。

Notice how the Java synchronized block construct takes an object in parentheses. In the example "this" is used, which is the instance the add method is called on. The object taken in the parentheses by the synchronized construct is called a monitor object. The code is said to be synchronized on the monitor object. A synchronized instance method uses the object it belongs to as monitor object.

对于同一个对象只能有一个线程访问同步块。

下面两个方法的代码,效果是一样的。

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

只能有一个线程执行(针对同一个对象) ;

第二个方法是不同的线程执行的时候会在同步块里面发生等待(针对同一对象)。

Synchronized Blocks in Static Methods

下面两个静态方法是在类对象上的:

  public class MyClass {

    public static synchronized void log1(String msg1, String msg2){
       log.writeln(msg1);
       log.writeln(msg2);
    }

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

一个线程只能在同一时间执行上面的任何一个方法。

对于第二个方法:只能有一个线程在代码块里面执行。

Java Synchronized Example


  public class MyClass {


    public static synchronized void log1(String msg1, String msg2){	 try {	    	    TimeUnit.SECONDS.sleep(5) ;	    	} catch (InterruptedException e) {	    	    e.printStackTrace();	    	}
       System.out.println(msg1);
       System.out.println(msg2);
    }
    
    public static synchronized void log3(String msg1, String msg2){	    System.out.println(msg1);	    System.out.println(msg2);  
    }
  
    public static void log2(String msg1, String msg2){
       synchronized(MyClass.class){	   try {	    	    TimeUnit.SECONDS.sleep(3) ;	    	} catch (InterruptedException e) {	    	    e.printStackTrace();	    	}	   System.out.println(msg1);	   System.out.println(msg2);  
       }
    }
    
    public static void log4(String msg1, String msg2){	synchronized(MyClass.class){	    	    System.out.println(msg1);	    System.out.println(msg2);  	}
    }
    
   
    public void log5(String msg1, String msg2){	synchronized(this){	    System.out.println(msg1);	    System.out.println(msg2);  	}
    }
    
  }
  public class SynchronizedTest {


    Thread t1 = new Thread(new Runnable() {
        
        @Override
        public void run() {
          
            MyClass.log1("msg11", "msg12") ;
        }
    }) ;
    Thread t2 = new Thread(new Runnable() {
        
        @Override
        public void run() {
           
            MyClass.log2("msg21", "msg22") ;
        }
    }) ;
    Thread t3 = new Thread(new Runnable() {		@Override	public void run() {	    	    MyClass.log3("msg31", "msg32") ;	}
    }) ;
    
    Thread t4 = new Thread(new Runnable() {		@Override	public void run() {	    	    MyClass.log4("msg41", "msg42") ;	}
    }) ;
    
    Thread t5 = new Thread(new Runnable() {		@Override	public void run() {	    	   new  MyClass().log5("msg51", "msg52") ;	}
    }) ;
    
    public static void main(String[] args) {	SynchronizedTest st = new SynchronizedTest() ;		st.t1.start() ;
//	st.t3.start() ;	//	st.t2.start() ;
//	st.t4.start() ;	st.t5.start() ;			 int i = 0 ;		while(true){		    try {			TimeUnit.SECONDS.sleep(1) ;			System.out.println("---------------> " + i);			i ++ ;					    } catch (InterruptedException e) {			e.printStackTrace();		    }		    if(i > 10 ){			    break ;		    }		}				    }
    
}

测试组合:

1. 测试实例方法组合;

2. 测试静态方法组合;

3. 测试实例方法和静态方法组合;(注意方法里面的 sleep, 是为了做到更好的测试效果)。


© 著作权归作者所有

丁佳辉
粉丝 20
博文 452
码字总数 206257
作品 0
浦东
程序员
私信 提问
【Java并发性和多线程】Java同步块

本文为转载学习 原文链接:http://tutorials.jenkov.com/java-concurrency/synchronized.html 译文链接:http://ifeve.com/synchronized-blocks/ Java 同步块(synchronized block)用来标记......

heroShane
2014/01/28
54
0
12、Java并发性和多线程-Java同步块

以下内容转自http://ifeve.com/synchronized-blocks/: Java 同步块(synchronized block)用来标记方法或者代码块是同步的。Java同步块用来避免竞争。本文介绍以下内容: Java同步关键字(s...

easonjim
2017/06/15
0
0
Java多线程学习(二)synchronized关键字(2)

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀
2018/04/16
0
0
Java Synchronized

Java Synchronized 1 引言 在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对synchronized进行了各种优化之后,有些情况下它并不那么重了...

秋风醉了
2016/03/18
140
0
synchronized与ThreadLocal

synchronized是实现java的同步机制。同步机制是为了实现同步多线程对相同资源的并发访问控制。保证多线程之间的通信。 同步的主要目的是保证多线程间的数据共享。同步会带来巨大的性能开销,...

bigYuan
2013/07/18
599
2

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
14
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
15
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部