Java 多线程(六) synchronized关键字详解

  多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同步用以解决多个线程同时访问时可能出现的问题。

  同步机制可以使用synchronized关键字实现。

  当synchronized关键字修饰一个方法的时候,该方法叫做同步方法。

  当synchronized方法执行完或发生异常时,会自动释放锁。

  下面通过一个例子来对synchronized关键字的用法进行解析。  

 

1.是否使用synchronized关键字的不同

例子程序1

 

  是否在execute()方法前加上synchronized关键字,这个例子程序的执行结果会有很大的不同。

  如果不加synchronized关键字,则两个线程同时执行execute()方法,输出是两组并发的。

  如果加上synchronized关键字,则会先输出一组0到9,然后再输出下一组,说明两个线程是顺次执行的。

 

2.多个方法的多线程情况

  将程序改动一下,Example类中再加入一个方法execute2()。

  之后再写一个线程类Thread2,Thread2中的run()方法执行的是execute2()。Example类中的两个方法都是被synchronized关键字修饰的。

例子程序2

   如果去掉synchronized关键字,则两个方法并发执行,并没有相互影响。

  但是如例子程序中所写,即便是两个方法:

  执行结果永远是执行完一个线程的输出再执行另一个线程的。  

  说明:

  如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到了某个synchronized方法,那么在该方法没有执行完毕前,其他线程是无法访问该对象的任何synchronized方法的。

  结论:

  当synchronized关键字修饰一个方法的时候,该方法叫做同步方法。

  Java中的每个对象都有一个锁(lock),或者叫做监视器(monitor),当一个线程访问某个对象的synchronized方法时,将该对象上锁其他任何线程都无法再去访问该对象的synchronized方法了(这里是指所有的同步方法,而不仅仅是同一个方法),直到之前的那个线程执行方法完毕后(或者是抛出了异常),才将该对象的锁释放掉,其他线程才有可能再去访问该对象的synchronized方法。

  注意这时候是给对象上锁,如果是不同的对象,则各个对象之间没有限制关系。

  尝试在代码中构造第二个线程对象时传入一个新的Example对象,则两个线程的执行之间没有什么制约关系。

 

3.考虑静态的同步方法

  当一个synchronized关键字修饰的方法同时又被static修饰,之前说过,非静态的同步方法会将对象上锁,但是静态方法不属于对象,而是属于类,它会将这个方法所在的类的Class对象上锁

  一个类不管生成多少个对象,它们所对应的是同一个Class对象。

例子程序3

 

  所以如果是静态方法的情况(execute()和execute2()都加上static关键字),即便是向两个线程传入不同的Example对象,这两个线程仍然是互相制约的,必须先执行完一个,再执行下一个。

 

  结论:

  如果某个synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchronized方法所在的类所对应的Class对象。Java中,无论一个类有多少个对象,这些对象会对应唯一一个Class对象,因此当线程分别访问同一个类的两个对象的两个static,synchronized方法时,它们的执行顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程才开始。

 

4. synchronized块

  synchronized块写法:

  synchronized(object)

  {      

  }

  表示线程在执行的时候会将object对象上锁。(注意这个对象可以是任意类的对象,也可以使用this关键字)。

  这样就可以自行规定上锁对象。 

 

例子程序4

  例子程序4所达到的效果和例子程序2的效果一样,都是使得两个线程的执行顺序进行,而不是并发进行,当一个线程执行时,将object对象锁住,另一个线程就不能执行对应的块。

  synchronized方法实际上等同于用一个synchronized块包住方法中的所有语句,然后在synchronized块的括号中传入this关键字。当然,如果是静态方法,需要锁定的则是class对象。

  

  可能一个方法中只有几行代码会涉及到线程同步问题,所以synchronized块比synchronized方法更加细粒度地控制了多个线程的访问,只有synchronized块中的内容不能同时被多个线程所访问,方法中的其他语句仍然可以同时被多个线程所访问(包括synchronized块之前的和之后的)。

  注意:被synchronized保护的数据应该是私有的

  结论:

  synchronized方法是一种粗粒度的并发控制,某一时刻,只能有一个线程执行该synchronized方法;

  synchronized块则是一种细粒度的并发控制,只会将块中的代码同步,位于方法内、synchronized块之外的其他代码是可以被多个线程同时访问到的。

 

JDK 5.0的并发包

  使用synchronized关键字解决线程的同步问题会带来一些执行效率上的问题。

  JDK1.4及之前是无法避免这些问题的。

  JDK 5.0引入了这样一个包:java.util.concurrent:

  http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-frame.html

  专门解决这一问题。

  限于篇幅,这里不再介绍。

 

参考资料

  圣思园张龙老师Java SE系列视频教程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/352304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java自动化_作为测试工程师进阶自动化选Java还是Python?

这是很多测试工程师从功能跨入自动化纠结的问题,今天本文带大家一探究竟。Java和Python一直都是两种很火的语言,用Python的一定觉得Python好,用Java的只觉得Java好。Java语言 VS Python语言Java自动化方法 VS Python自动化方法综上所述&…

Spring –添加Spring MVC –第2部分

在上一部分中,我们为经理和员工实现了控制器。 既然我们知道了自己的出路,我们将做很少(但仅做很少)更复杂的事情-任务和时间表的控制器。 因此,让我们从org.timesheet.web开始。 TaskController 。 首先创建一个类&am…

CALL SYMPUT与CALL SYMPUTX区别

call symput 在data步中将值塞入宏变量http://www2.sas.com/proceedings/sugi29/052-29.pdf [SAS] CALL SYMPUT与CALL SYMPUTX CALL SYMPUT的功能是可以在DATA step内将值塞到一个macro变量里面。如果这个macro变量已经存在,那这个call就会更新该macro变量的值。 CA…

Linux基本结构

一个完整地Linux操作系统由4部分组成,即内核(Kernel)、外壳(Shell)、实用程序(Utilities)和应用程序(Applications)。 (1)内核是Linux的心脏&…

jmeter使用_jmeter工具的使用

1.本地下载到官网,5.3版本的对应的是jdk8版本,就用这个了2.解压进入bin目录,找到jmeter.bat启动它,会弹出两个窗口,一个是启动窗口,使用jmeter不可以关了它,另一个是jmeter的工作界面进入界面默…

UliPad 初体验----python 开发利器

学习python 有段时间,最近博客更新比较慢了,空闲时间在零零碎碎的学python ,难成文,也就没整理成博客。 学习python 最苦恼的就是没有趁手IDE ,之前学java 时 Eclipse 肯定是不二之选。eclipse pydev 也可以开发python…

Neo4j:找到两个纬度/经度之间的中点

在过去的两个周末中,我一直在处理一些运输数据,并且我想运行A *算法来查找两个车站之间的最快路线。 A *算法将一个EstimateEvaluator作为其参数之一,然后该评估器查看节点的经度/纬度,以确定一条路径是否值得遵循。 因此&#x…

猫狗大战

可行性背包 令dp[i][j]表示选i个人能否达到j这个状态,那么转移就和背包一样了,外层枚举选哪一个(K),2、3层枚举i,j,那么\[dp[i][j] | dp[i-1][j-val[k]];\] 转载于:https://www.cnblogs.com/bullshit/p/9902003.html

SAS的数组array介绍

SAS可以把一组同为数值型或同为字符型的变量合在一起,使用同一个名字称呼,用下标来区分。这与通常的程序设计语言中的数组略有区别,通常的程序设计语言中数组元素没有对应的变量名,而SAS数组每个元素都有自己的变量名。 一、数值型…

python while循环if_详解python基础之while循环及if判断

wlile循环while True表示永远为真,不管是什么条件都会向下执行,下面是写的一个例子。#!/usr/bin/env pythonage 24                            #给age赋一个值while True:                       …

关于页面的多种自适应布局——两列布局

我们在切页面的时候打交道最多的就是关于布局排版的技巧&#xff0c;我这里总结了一些平时做页面时用的到各种布局技巧&#xff0c;作为笔记便于日后随时查询。 1、简单结构1&#xff0c;列表在前&#xff0c;内容在后 1 <style type"text/css">2 .layout{back…

很全的sas基础知识

5.1 SAS表达式简介   &#xff11;&#xff0e;SAS常数表达式   (1)数值常数 如: 1.23、 -5、 0.5E-10。   (2)字符常数 如: name1TOME、 name2MARY、name3JOHN。   (3)日期(d)、时间(t)、日时(dt)常数 如: d101JAN80d、t19:25:19t、   dt118JAN80:9:27:05dt。  …

kitti数据集_KITTI数据集激光雷达坐标系下的里程计真值

由KITTI数据集Odometry模块的devkit_odometrydevkitreadme.txt所述&#xff0c;KITII数据集提供里程计的真值是在左相机表坐标系下的&#xff0c;并没有提供激光雷达坐标系下的真值。因此&#xff0c;求得激光雷达坐标系下的真值&#xff0c;对我们使用KITTI数据集进行点云处理…

python中文处理

一、使用中文字符 在python源码中如果使用了中文字符&#xff0c;运行时会有错误&#xff0c;解决的办法是在源码的开头部分加入字符编码的声明&#xff0c;下面是一个例子&#xff1a;#!/usr/bin/env python# -*- coding: cp936 -*-Python Tutorial中指出&#xff0c;python的…

信号量使用例子_用信号量锁定:一个例子

信号量使用例子并发是带来有趣挑战的一个方面。 如果处理不当&#xff0c;会带来种族问题&#xff0c;这会使人们感到困惑&#xff0c;因为这些问题有时会突然出现&#xff0c;并且有时会正常工作。 当处理访问公共资源的并发线程时&#xff0c;Java语言提供了许多处理竞争条件…

.net Reactor之exe、dll文件混淆

.net Reactor之exe、dll文件混淆 .net Reactor的主要功能&#xff1a; 1.是对dll文件、exe文件进行反编译混淆 2.对dll进行内部加锁&#xff0c;限制其使用的固定机器、固定时间、部署次数 2.创建证书文件&#xff0c;用证书管理其限制的机器、时间、部署次数 页面&#xff1a;…

简述SAS逻辑库的概念及建立方法。什么是临时库和永久库?

libname student e:\mysas;SAS中利用libname命令建立逻辑库&#xff0c;虽然之后建立的与其关联的永久数据集还保存在该逻辑库所指的目录中&#xff0c;但重启SAS后该库却没有显示于库目录中。 例如e:\mysas目录已存在&#xff0c;程序data student.aaa;……重启SAS后虽然数据集…

35 岁 学python 必要_程序员:Python学不学?完全没必要纠结

随着云计算、大数据、人工智能的大量应用&#xff0c;Python这毛头小子&#xff0c;成了当红炸子鸡&#xff0c;香飘四溢&#xff0c;撒播到互联网的每个角落里。1几家欢喜几家愁&#xff0c;欢喜的人&#xff0c;早就用上了&#xff0c;国外的Twitter、Google、Yahoo&#xff…

了解连接池

1.简介 连接池是一种通过在池中打开和管理N个数据库连接来提高应用程序性能的技术。 该应用程序只是请求连接&#xff0c;使用它&#xff0c;然后将其放回池中。 当应用程序需要连接时&#xff0c;就绪连接将保持可用状态&#xff0c;以供池中使用。 池管理连接生命周期&#x…

linux上很方便的上传下载文件工具rz和sz

linux上很方便的上传下载文件工具rz和sz(本文适合linux入门的朋友) ######################################################### #《老男孩linux就业培训中心-初级班第七期第一节内容总结。 #linux上很方便的上传下载文件工具rz和sz #date:2011-06-15 #作者&#xff1a;老男孩…