关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。本文探讨synchronized关键字。

synchronized关键字可以修饰方法,可以修饰代码块,但不能修饰构造器、属性等。

对synchronized(this)的一些理解

  1. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
  2. 当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
  3. 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的除synchronized(this)同步代码块以外的部分。
  4. 第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
  5. 以上规则对其它对象锁同样适用。

一:synchronized同步代码块

  1. package com.clzhang.sample.thread;
  2.  
  3. public class SyncThread1 implements Runnable {
  4. private Integer key = 0;
  5.  
  6. @Override
  7. public void run() {
  8. // key是Integer对象(注意不是int,因为int不是对象)
  9. // 线程进入下面同步代码之前,需要先获取key的锁。
  10. // 需要结果是key实现自增长,如果没有同步块,则可能会出现重复key值的现象
  11. synchronized (key) {
  12. key++;
  13.  
  14. System.out.println(Thread.currentThread().getName() + ":" + key);
  15. try {
  16. Thread.sleep(100);
  17. } catch (InterruptedException e) {
  18. }
  19. }
  20. }
  21.  
  22. public static void main(String[] args) {
  23. SyncThread1 st = new SyncThread1();
  24.  
  25. for(int i=0; i<10; i++) {
  26. new Thread(st, "Thread" + i).start();
  27. }
  28. }
  29. }

输出:

Thread1:2
Thread3:3
Thread5:4
Thread7:5
Thread0:2
Thread2:7
Thread9:6
Thread4:8
Thread6:9
Thread8:10

二:synchronized同步方法

同步方法分静态和非静态两种。静态方法则一定会同步,非静态方法需在单例模式才生效,推荐用静态方法(不用担心是否单例)。

2.1 非静态方法同步示范

  1. package com.clzhang.sample.thread;
  2.  
  3. // 如果是同步方法,则分静态和非静态两种。
  4. // 静态方法则一定会同步,非静态方法需在单例模式才生效,推荐用静态方法(不用担心是否单例)。
  5. public class SyncThread2 implements Runnable {
  6. private Integer key = 0;
  7.  
  8. // 此示范为非静态方法同步
  9. public synchronized Integer getKey() {
  10. key++;
  11.  
  12. return key;
  13. }
  14.  
  15. @Override
  16. public void run() {
  17. System.out.println(Thread.currentThread().getName() + ":" + getKey());
  18. try {
  19. Thread.sleep(10);
  20. } catch (InterruptedException e) {
  21. }
  22. }
  23.  
  24. public static void main(String[] args) {
  25. // 非静态方法同步,需要启动单例模式
  26. SyncThread2 st = new SyncThread2();
  27. for (int i = 0; i < 10; i++) {
  28. new Thread(st, "Thread" + i).start();
  29. }
  30. }
  31. }

输出:

Thread0:1
Thread1:3
Thread2:2
Thread3:5
Thread5:6
Thread7:7
Thread9:8
Thread6:9
Thread8:10
Thread4:4

2.2 静态方法同步示范

  1. package com.clzhang.sample.thread;
  2.  
  3. // 如果是同步方法,则分静态和非静态两种。
  4. // 静态方法则一定会同步,非静态方法需在单例模式才生效,推荐用静态方法(不用担心是否单例)。
  5. public class SyncThread3 implements Runnable {
  6. private static Integer key = 0;
  7.  
  8. // 此示范为静态方法同步
  9. public synchronized static Integer getKey() {
  10. key++;
  11.  
  12. return key;
  13. }
  14.  
  15. @Override
  16. public void run() {
  17. System.out.println(Thread.currentThread().getName() + ":" + getKey());
  18. try {
  19. Thread.sleep(10);
  20. } catch (InterruptedException e) {
  21. }
  22. }
  23.  
  24. public static void main(String[] args) {
  25.  
  26. // 如果用静态方法实现同步,则可以生成对象的多个实例
  27. for (int i = 0; i < 10; i++) {
  28. SyncThread3 st = new SyncThread3();
  29. new Thread(st, "Thread" + i).start();
  30. }
  31. }
  32. }

输出:

Thread3:3
Thread1:1
Thread0:2
Thread5:4
Thread7:5
Thread9:6
Thread2:7
Thread8:10
Thread6:9
Thread4:8

总结

1、无论是同步代码块还是同步方法,必须获得对象锁才能够进入同步代码块或者同步方法进行操作。

2、如果采用方法级别的同步,对象锁为方法所在的对象;如果是静态同步方法,对象锁为方法所在的类(唯一)。

3、对于代码块,对象锁即指synchronized(object)中的object。

Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)的更多相关文章

  1. Java多线程4:synchronized关键字

    原文:http://www.cnblogs.com/skywang12345/p/3479202.html 1. synchronized原理在java中,每一个对象有且仅有一个同步锁.这也意味着,同 ...

  2. 【synchronized锁】通过synchronized锁 反编译查看字节码指令分析synchronized关键字修饰方法与代码块的区别

    前提: 首先要铺垫几个前置的知识: Java中的锁如sychronize锁是对象锁,Java对象头中具有标识位,当对象锁升级为重量级锁时,重量级锁的标识位会指向监视器monitor, 而每个Java对 ...

  3. JAVA多线程之Synchronized关键字--对象锁的特点

    一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...

  4. “全栈2019”Java多线程第十六章:同步synchronized关键字详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  5. Java多线程 - 线程同步

    多线程操作同一个对象时,容易引发线程安全问题.为了解决线程安全问题,Java多线程引入了同步监视器. 同步代码块 同步代码块语法格式如下: synchronized(obj){ //此处的代码即为同步 ...

  6. Java多线程——线程之间的同步

    Java多线程——线程之间的同步 摘要:本文主要学习多线程之间是如何同步的,如何使用volatile关键字,如何使用synchronized修饰的同步代码块和同步方法解决线程安全问题. 部分内容来自以 ...

  7. java中synchronized关键字的用法

    在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识. j ...

  8. Java关键字-----------------java中synchronized关键字的用法

    在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识. j ...

  9. Java基础-synchronized关键字的用法(转载)

    synchronized--同步 顾名思义是用于同步互斥的作用的. 这里精简的记一下它的使用方法以及意义: 当synchronized修饰 this或者非静态方法或者是一个实例的时候,所同步的锁是加在 ...

  10. Java多线程-线程的同步(同步方法)

    线程的同步是保证多线程安全访问竞争资源的一种手段.线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些 ...

随机推荐

  1. python使用md5处理下载图片

    import urllib2 import hashlib opener = urllib2.build_opener() req = opener.open("http://avatar. ...

  2. css样式记录

    样式一 #sideBar,#blog_post_info_block { display: none; } #under_post_news { display: none; } /*评论框大小*/ ...

  3. spring源代码系列(一)sring源代码编译 spring源代码下载 spring源代码阅读

    想对spring框架进行深入的学习一下,看看源码,提升和沉淀下自己,工欲善其事必先利其器,还是先搭建好开发环境吧. 环境搭建 sping源代码之前是svn管理,如今已经迁移到了github中了.新版本 ...

  4. android触控,先了解MotionEvent

    MotionEvent源代码可以在ocs看到,当然你也可以在SDK中下载源代码,或者其他地方,如: https://github.com/CyanogenMod/android_frameworks_ ...

  5. STL - Map - 运行期自定义排序

    RuntimeStringCmp.cpp #include <string> using namespace std; // function object to compare stri ...

  6. 【Linux】关于Linux的部分细节与配置文件

    文章对Linux的启动过程 进行了讲解,摘录一些要点,(摘自:https://www.ibm.com/developerworks/cn/linux/l-linuxboot/)如下: 当系统首次引导时 ...

  7. webpack打包过滤console.log

    在webpack.prod.conf.js里面的plugins里面加上 drop_debugger: true, drop_console: true new webpack.optimize.Ugl ...

  8. CSDN日报20170310——《假如我是一行代码》

    [程序人生]假如我是一行代码 作者:henry-hacker 我们不止一次在生活中听到"假如我如何如何,我会如何如何"的句式.而这种句式说出来的一般意义无非就是让我们站在还有一个角 ...

  9. Canvas简述

    HTML Canvas API有两方面优势可以弥补:首先,不需要将所绘制图像中的每个图元当做对象存储,因此执行性能非常好:其次,在其他编程语言现有的优秀二维绘图API的基础上实现Canvas API相 ...

  10. 如何查询端口号和网址的ip地址?

    import socket print socket.gethostname()#主机名 hostname=socket.gethostname() #传递主机名 print socket.getho ...