java同步锁如何使用_java 同步锁(synchronized)的正确使用姿势

关于线程安全,线程锁我们经常会用到,但你的使用姿势正确不,反正我用错了好长一段时间而不自知。所以有了这篇博客总结下线程锁的正确打开姿势

废话不说看例子

一,对整个方法进行加锁

1,对整个方法进行加锁,不同线程访问同一个类的同一个对象

public class TestRunnable implements Runnable {

@Override

public synchronized void run() {

// TODO Auto-generated method stub

for(int i=0;i<10;i++)

{

try {

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"---"+i);

}

}

}public static void main(String[] args)

{

TestRunnable runnable=new TestRunnable();

Thread threadA=new Thread(runnable,"threadA");

threadA.start();

Thread threadB=new Thread(runnable,"threadB");

threadB.start();

}

运行结果:

threadA---0

threadA---1

threadA---2

threadA---3

threadA---4

threadA---5

threadA---6

threadA---7

threadA---8

threadA---9

threadB---0

threadB---1

threadB---2

threadB---3

threadB---4

threadB---5

threadB---6

threadB---7

threadB---8

threadB---9

2,对整个方法进行加锁,不同线程访问同一个类的不同对象

public class TestRunnable implements Runnable {

@Override

public synchronized void run() {

// TODO Auto-generated method stub

for(int i=0;i<10;i++)

{

try {

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"---"+i);

}

}

}public static void main(String[] args)

{

TestRunnable runnableA=new TestRunnable();

Thread threadA=new Thread(runnableA,"threadA");

threadA.start();

TestRunnable runnableB=new TestRunnable();

Thread threadB=new Thread(runnableB,"threadB");

threadB.start();

}

运行结果:

threadB---0

threadA---0

threadA---1

threadB---1

threadA---2

threadB---2

threadA---3

threadB---3

threadB---4

threadA---4

threadA---5

threadB---5

threadA---6

threadB---6

threadA---7

threadB---7

threadA---8

threadB---8

threadA---9

threadB---9

小结:对方法整体加锁的做法适用条件是 多个线程访问的必须是同一个类的同一个实例对象

一,对代码块进行加锁

1,对代码块进行加锁,加锁对象为当前类对象,不同线程访问同一个类的同一个对象

public class TestRunnable implements Runnable {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized (TestRunnable.this) {

for (int i = 0; i < 10; i++) {

try {

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "---" + i);

}

}

}

}public static void main(String[] args)

{

TestRunnable runnable=new TestRunnable();

Thread threadA=new Thread(runnable,"threadA");

threadA.start();

Thread threadB=new Thread(runnable,"threadB");

threadB.start();

}

运行结果:

threadA---0

threadA---1

threadA---2

threadA---3

threadA---4

threadA---5

threadA---6

threadA---7

threadA---8

threadA---9

threadB---0

threadB---1

threadB---2

threadB---3

threadB---4

threadB---5

threadB---6

threadB---7

threadB---8

threadB---9

2,对代码块进行加锁,加锁对象为当前类对象,不同线程访问同一个类的不同对象

public class TestRunnable implements Runnable {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized (TestRunnable.this) {

for (int i = 0; i < 10; i++) {

try {

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "---" + i);

}

}

}

}

public static void main(String[] args)

{

TestRunnable runnableA=new TestRunnable();

Thread threadA=new Thread(runnableA,"threadA");

threadA.start();

TestRunnable runnableB=new TestRunnable();

Thread threadB=new Thread(runnableB,"threadB");

threadB.start();

}

运行结果:

threadB---0

threadA---0

threadB---1

threadA---1

threadB---2

threadA---2

threadA---3

threadB---3

threadA---4

threadB---4

threadB---5

threadA---5

threadA---6

threadB---6

threadB---7

threadA---7

threadA---8

threadB---8

threadA---9

threadB---9

3,对代码块进行加锁,加锁对象为当前类(不是类对象哦),不同线程访问同一个类的同一个对象

public class TestRunnable implements Runnable {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized (TestRunnable.class) {

for (int i = 0; i < 10; i++) {

try {

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "---" + i);

}

}

}

}public static void main(String[] args)

{

TestRunnable runnable=new TestRunnable();

Thread threadA=new Thread(runnable,"threadA");

threadA.start();

Thread threadB=new Thread(runnable,"threadB");

threadB.start();

}

运行结果:

threadA---0

threadA---1

threadA---2

threadA---3

threadA---4

threadA---5

threadA---6

threadA---7

threadA---8

threadA---9

threadB---0

threadB---1

threadB---2

threadB---3

threadB---4

threadB---5

threadB---6

threadB---7

threadB---8

threadB---9

4,对代码块进行加锁,加锁对象为当前类(不是类对象哦),不同线程访问同一个类的不同对象

public class TestRunnable implements Runnable {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized (TestRunnable.class) {

for (int i = 0; i < 10; i++) {

try {

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "---" + i);

}

}

}

}public static void main(String[] args)

{

TestRunnable runnableA=new TestRunnable();

Thread threadA=new Thread(runnableA,"threadA");

threadA.start();

TestRunnable runnableB=new TestRunnable();

Thread threadB=new Thread(runnableB,"threadB");

threadB.start();

}

运行结果:

threadA---0

threadA---1

threadA---2

threadA---3

threadA---4

threadA---5

threadA---6

threadA---7

threadA---8

threadA---9

threadB---0

threadB---1

threadB---2

threadB---3

threadB---4

threadB---5

threadB---6

threadB---7

threadB---8

threadB---9

5,对代码块进行加锁,加锁对象为已赋值的变量,不同线程访问同一个类的同一个对象

public class TestRunnable implements Runnable {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized ("test") {

for (int i = 0; i < 10; i++) {

try {

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "---" + i);

}

}

}

}public static void main(String[] args)

{

TestRunnable runnable=new TestRunnable();

Thread threadA=new Thread(runnable,"threadA");

threadA.start();

Thread threadB=new Thread(runnable,"threadB");

threadB.start();

}

运行结果:

threadA---0

threadA---1

threadA---2

threadA---3

threadA---4

threadA---5

threadA---6

threadA---7

threadA---8

threadA---9

threadB---0

threadB---1

threadB---2

threadB---3

threadB---4

threadB---5

threadB---6

threadB---7

threadB---8

threadB---9

6,对代码块进行加锁,加锁对象为已赋值的变量,不同线程访问同一个类的不同对象

public class TestRunnable implements Runnable {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized ("test") {

for (int i = 0; i < 10; i++) {

try {

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "---" + i);

}

}

}

}public static void main(String[] args)

{

TestRunnable runnableA=new TestRunnable();

Thread threadA=new Thread(runnableA,"threadA");

threadA.start();

TestRunnable runnableB=new TestRunnable();

Thread threadB=new Thread(runnableB,"threadB");

threadB.start();

}

运行结果:

threadA---0

threadA---1

threadA---2

threadA---3

threadA---4

threadA---5

threadA---6

threadA---7

threadA---8

threadA---9

threadB---0

threadB---1

threadB---2

threadB---3

threadB---4

threadB---5

threadB---6

threadB---7

threadB---8

threadB---9

小结:当对代码块进行加锁时,当加锁对象是一个确定值时(当前类,或者已赋值的变量) 不同线程访问同一个类的不同对象时也可以实现线程同步

最后奉上线程锁在实际开发中的应用----单例模式

1,懒汉式写法

public class Singleton {

private static Singleton instance;

private Singleton (){}

public static synchronized Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

}2,懒汉式写法升级版(双重校验锁) 性能优于第一种

public class Singleton {

private static Singleton singleton;

private Singleton (){}

public static Singleton getSingleton() {

if (singleton == null) {

synchronized (Singleton.class) {

if (singleton == null) {

singleton = new Singleton();

}

}

}

return singleton;

}

}

3,饿汉式写法,不依赖于线程同步锁,依赖于静态变量和类的同步加载实现线程安全public class Singleton {

private static Singleton instance = new Singleton();

private Singleton (){}

public static Singleton getInstance() {

return instance;

}

}

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

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

相关文章

IDE--ubuntu下安装 Source insight

2013-06-03 09:05 74人阅读 评论(0) 收藏 举报 习惯了在source insight下编辑阅读源码&#xff0c;在linux下用vi总是用不好 &#xff0c;还是在ubuntu上用回熟悉的source insight。 在ubuntu中&#xff0c;安装windows程序用wine&#xff0c;然后用wine安装windows软件即可。…

python中什么是数据驱动_利用Python如何实现数据驱动的接口自动化测试

前言 大家在接口测试的过程中&#xff0c;很多时候会用到对CSV的读取操作&#xff0c;本文主要说明Python3对CSV的写入和读取。下面话不多说了&#xff0c;来一起看看详细的介绍吧。 1、需求 某API&#xff0c;GET方法&#xff0c;token,mobile,email三个参数 token为必填项 mo…

密码锁 java接口_从synchronized和lock区别入手聊聊java锁机制

写这篇文章之前&#xff0c;我去百度了一下啥叫锁&#xff0c;百度百科上写道&#xff1a;置于可启闭的器物上&#xff0c;以钥匙或暗码开启。确实我们一般理解的锁就是门锁&#xff0c;密码锁&#xff0c;但是在计算机科学中&#xff0c;锁又是啥&#xff0c;说实话&#xff0…

对cookie和子cookie操作的封装

1 /**2 * 封装cookie的操作3 * type {Object}4 */5 var CookieUtil {6 /**7 * 根据cookie的名字获取相应的值8 * param name cookie名字9 * return {*}10 */11 get:function (name) {12 //对name进行URL编码13 var cookieName…

解决Ubuntu下切换到root用户后没有声音问题

Ubuntu在root用户下&#xff0c;为了安全考虑默认是关闭了声音系统的。 如果要开很简单&#xff0c;因为root登录后pulseaudio没有启动。所以要先启动它 将root加到pulse和pulse-access组&#xff1a; sudo usermod -a -G pulse-access root gpasswd -a root pulse gpasswd -…

lua 给userdata设置元表_lua学习之复习汇总篇

第六日笔记1. 基础概念程序块定义在 lua 中任何一个源代码文件或在交互模式中输入的一行代码程序块可以是任意大小的程序块可以是一连串语句或一条命令也可由函数定义构成&#xff0c;一般将函数定义写在文件中&#xff0c;然后用解释器执行这个文件换行在代码中不起任何作用&a…

java代码请求2次_Android基于OkHttpUtils网络请求的二次封装

OkHttpUtils网络请求为什么进行二次封装&#xff1f;1、减少代码量2、后期换网络处理框架方便二次封装的实现原理1、将网络请求提取在一个方法中2、对里面的可变参数,可以通过参数传递过去,也可以提供一个set方法传递过去3、对于请求失败和成功,我们可以使用接口回调,让调用该方…

集群服务负载均衡------LVS

个人的理解&#xff0c;以一种通俗易懂的方式讲述出来&#xff0c;如果有哪些地方说的不正确的话&#xff0c;希望大家留言指出来。笔者会非是常的感谢&#xff01; Cluster服务器集群&#xff0c;直接理解为一些单一的服务器的集合通过某种方式组合起来&#xff0c;为客户端提…

Cubieboard2 debian

环境准备 本文所使用的主机环境为kubuntu 12.10&#xff0c;然而一般情况下&#xff0c;下面涉及到的命令对基于Debian的(X)ubuntu系列都应该适用。 为不引起混淆&#xff0c;我们作如下约定&#xff1a; 工作目录为 $WORK_DIR,目标系统 rootfs 目录为 $WORK_DIR/$ROOTFS_DIR命…

linux和python的关系_Python、Linux与我的缘分

是在大二时期&#xff0c;那时候不懂什么技术&#xff0c;所以就选择了 Ubuntu 来学习、 使用&#xff0c; 它好操作、 界面绚丽、 简单易用&#xff0c; 对于我这种 Linux 新手来说知足了。 毕竟没玩过 Linux &#xff0c;知识有限&#xff0c; 玩不转 Linux 的种种配置&#…

linux 磁盘uuid获取

ls -l /dev/disk/by-uuid/总用量 0lrwxrwxrwx 1 root root 10 2012-08-15 09:28 0af9bc87-c3c9-49eb-829e-caf572298cc7 -> http://www.cnblogs.com/sdb1lrwxrwxrwx 1 root root 10 2012-08-15 09:27 3e8b5c85-3f5b-4864-b45e-03ff0073eb5f -> http://www.cnblogs.com/sd…

tomcat jsp导入java_[导入]Tomcat JSP Web 开发中的乱码问题小姐

1. 静态页面的乱码问题文件的编码和浏览器要显示的编码不一致。1) 检查文件原始的编码, 可以用记事本打开, 然后选择另存为来看;2) 给当前页面加入一个指令来建议浏览器用指定的编码来显示文件字符内容.3) 如果系统是英文XP,没装东亚字符集支持, 也会显示乱码.2. JSP 页面的乱码…

编译Mysql 5.5时报do_abi_check错误

下载mysql-5.5.3-m3源码后&#xff0c;执行configure无错误&#xff0c;在make的时候却报: make[2]: *** [do_abi_check] 错误 1<br> make[2]: Leaving directory /tmp/mysql-5.5.3-m3<br> make[1]: *** [abi_check] 错误 2<br> make[1]: Leaving directory …

四大开源分布式存储_ipfs分布式存储行业面临着四大主要风险,你知道是哪些吗?...

为了响应国家号召、推动分布式存储技术落地、防御行业风险&#xff0c;中国分布式存储产业联盟启动&#xff0c;全国从事IPFS以及分布式存储从业者对行业风险及联盟成立的必要性达成了高度共识&#xff0c;目前有36家以上的IPFS分布式存储行业企业填写了联盟申请表。几位国内知…

mathematica打包java_从Mathematica到Java的图像

我试图从Mathematica中获取一张图片.我尝试评估一些使用包中的方法生成图形的Mathematica代码.如果我将代码粘贴到Mathematica Notebook,则会正确生成图形.所以我的问题&#xff1a;如何将这些图形转换为Java ???这是我的示例代码&#xff1a;ml MathLinkFactory.createKer…

pjsua帮助手册(中文)

原文地址 : http://www.pjsip.org/pjsua.htm 介绍 PJSUA是一个开源的命令行SIP用户代理&#xff08;软电话&#xff09;&#xff0c;用PJSIP协议&#xff0c;PJNATH&#xff0c;和PJMEDIA实现。 它虽然只有很简单的命令行界面&#xff0c;但是功能齐全。 SIP功能&#xff1a; 多…

c/c++笔试面试题(4)

c/c笔试面试题&#xff08;4&#xff09; 2007-11-08 16:46 749人阅读 评论(0) 收藏 举报Sony笔试题 1&#xff0e;完成下列程序 * *.*. *..*..*.. *...*...*...*... *....*....*....*....*.... *.....*.....*.....*.....*.....*..... *......*......*......*......*......*...…

js date转成 时间字符串_秋招快要开始了,前端笔试中的坑位-JS隐式转换问题

我们在写笔试题的时候&#xff0c;经常碰到涉及隐式转换的题目&#xff0c;例如"1" 2 obj 1 [] ![] [null] false 和 叫做严格运算符&#xff0c;对象类型指向地址相同或原始类型&#xff08; 数值、字符串、布尔值&#xff09;值相同&#xff1b;叫做相等运算…

Java中快速处理集合_简洁又快速地处理集合——Java8 Stream(上)

作者&#xff1a;Howie_Y&#xff0c;系原创投稿主页&#xff1a;www.jianshu.com/u/79638e5f0743Java 8 发布至今也已经好几年过去&#xff0c;如今 Java 也已经向 11 迈去&#xff0c;但是 Java 8 作出的改变可以说是革命性的&#xff0c;影响足够深远&#xff0c;学习 Java …

FTP服务器和客户端源代码编写问题(ftp server client source)

最近关注FTP程序源代码的朋友非常多&#xff0c;这里简单说明一下。 其实FTP也就是普通的Socket程序&#xff0c;只是需要按照FTP协议(RFC959, 1635?可能我记错了)去做&#xff0c;也就是每个消息有固定的结构的&#xff0c;比如头3个字节必须是200,201,300,400之类的数字表示…