@Java | Thread synchronized - [ 线程同步锁 基本使用]

对实现了Runnable或者Callable接口类,可以通过多线程执行同一实例的runcall方法,那么对于同一实例中的局部变量(非方法变量)就会有多个线程进行更改或读取,这就会导致数据不一致,synchronized(关键字)可以解决多线程共享数据同步的问题

synchronized使用说明

作用范围

synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
  1. 修饰一个代码块:被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象
  2. 修饰一个非静态方法:被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象
  3. 修改一个静态的方法:其作用的范围是整个静态方法,作用的对象是这个类的所有对象
  4. 修改一个类:其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象
高能提示:
No1 > synchronized修饰的非静态方法:如果一个对象多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,则这个线程所属对象其它线程不能同时访问这个对象任何一个synchronized方法
No2 > synchronized关键字是不能继承的:基类的方法synchronized function(){}在继承类中并不自动是synchronized function(){},而是变成了function(){}。继承类需要你显式的指定它的某个方法为synchronized方法,可以通过子类调用父类的同步方法来实现同步
No3 > 针对synchronized修饰代码块和非静态方法,本质上锁的是代码块或非静态方法对应的对象代码块是synchronized标注的变量,非静态方法是所在类对应的实例),如果是不同的对象是可以同时访问的
No4 > 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制
No5 > 每个对象只有一个锁(lock)与之相关联
No6 > 在定义接口方法时不能使用synchronized关键字
No7 > 构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步

1. 修饰一个代码块

public void syncCode(Object o) {synchronized (o) {// 同步代码块}
}
上面的锁就是o这个对象,当然多个线程同步需要保证o这个对象是同一个,这是有明确的对象作为锁的情况,如果只是想单纯的让某一段代码同步,并没有明确的对象作为锁,可以创建一个特殊的instance变量来充当锁
synchronized(o)修饰的代码块,其中o可以取值一个对象或者一个变量或者this亦或者Clz.class
public class Sync implements Runnable {private byte[] lock = new byte[0];public void syncCode() {synchronized (lock) {// 同步代码块}}public void run ....
}
零长度的byte数组对象创建起来将比任何对象都经济,查看编译后的字节码,生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码

2. 修饰一个非静态方法

public synchronized void method() {// .....}
此时锁的是调用这个同步方法的对象

3. 修饰一个静态方法

public synchronized static void method() {// .....}
synchronized修饰的静态方法锁定的是这个类的所有对象

4. 修饰类

public class Sync implements Runnable {public void syncCode() {synchronized (Sync.class) {// 同步代码块}}public void run ....
}
和作用于静态方法一样,synchronized作用于一个类时,是给这个类加锁,类的所有对象用的是同一把锁

总结

  1. 线程同步的目的是为了保护多个线程反问一个资源时对资源的破坏。
  2. 线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他非同步方法
  3. 对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁,当在一个同步方法中访问另外对象上的同步方法时,会获取这两个对象锁。
  4. 对于同步,要时刻清醒在哪个对象上同步,这是关键。
  5. 编写线程安全的类,需要时刻注意对多个线程竞争访问资源的逻辑和安全做出正确的判断,对"原子"操作做出分析,并保证原子操作期间别的线程无法访问竞争资源。
  6. 当多个线程等待一个对象锁时,没有获取到锁的线程将发生阻塞。
  7. 死锁是线程间相互等待锁锁造成的,在实际中发生的概率非常的小,一旦程序发生死锁,程序将死掉

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

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

相关文章

激活prompt

1.下载SQLPrompt 2. 断网, 打开注册机,拷贝验证码 2. 点击activate, 拷贝代码 转载于:https://www.cnblogs.com/zxhome/p/9459415.html

[转]自然语言处理中的Attention Model:是什么及为什么

自然语言处理中的Attention Model:是什么及为什么 https://blog.csdn.net/malefactor/article/details/50550211/* 版权声明:可以任意转载,转载时请标明文章原始出处和作者信息 .*/ author: 张俊林 要是关注深度学习在自然语言处理方面…

用gson得JSON,数值变为double类型 ,去掉double值中的小数位(3.0改为3)

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1. 项目中有个接口的数据是从缓存中读取再组成JSON 格式返出,原本缓存中数据是这样的: 用Gson 组成JSON 后&…

38--合并两个排序的链表

1.问题描述 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。 实例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 2.解决思路 /*** Definition for singly-linked lis…

39--打印从1到最大的n位数

1.题目描述 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。 示例 1: 输入: n 1 输出: [1,2,3,4,5,6,7,8,9] 2.解题思路 class Solution {public int[] printNumbers(int n) {int end …

Python学习之路20-数据模型

《流畅的Python》笔记。本篇是Python进阶篇的开始。本篇主要是对Python特殊方法的概述。1. 前言 数据模型其实是对Python框架的描述,它规范了这门语言自身构件模块的接口,这些模块包括但不限于序列、迭代器、函数、类和上下文管理器。不管在哪种框架下写…

《netty实战》阅读笔记(2)——Netty 的数据容器ByteBuf

ByteBuffer 当我们进行数据传输的时候,往往需要使用到缓冲区,常用的缓冲区就是JDK NIO类库提供的java.nio.Buffer。 实际上,7种基础类型(Boolean除外)都有自己的缓冲区实现,对于NIO编程而言,我们…

32位Windows7上8G内存使用感受+xp 32位下使用8G内存

我推荐做开发的朋友:赶快加入8G的行列吧....呵呵..超爽...速度超快...基本没有等待的概念...深有体会... 为什么要使用8G内存?在国内外各大论坛上,这都是一个有争议的问题。问题的反方论据非常充分: 除了少数专业领域,大多数应用程…

面试常考的数据结构Java实现

1、线性表 2、线性链表 3、栈 4、队列 5、串 6、数组 7、广义表 8、树和二叉树 二叉树:每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。 二叉…

Java5线程并发库之LOCK(锁)CONDITION(条件)实现线程同步通信

为什么80%的码农都做不了架构师?>>> Lock(锁)&Condition(条件)实现线程同步通信 接下来介绍,java5线程并发库里面的锁。跟锁有关的类和接口主要是位于java.util.concurrent.locks包。 Lock…

逻辑运算符与逻辑表达式

1 #include <stdio.h>2 3 int main()4 {5 int a0;int b0;6 if(a&&b)//a&&ba的逻辑值为0&#xff0c;则执行else7 {8 printf("a&&b is true\n");9 } 10 else 11 { 12 printf("a&&…

网站性能优化的三重境界

这篇文章是关于网站性能优化体验的&#xff0c;性能优化是一个复杂的话题&#xff0c;牵涉的东西非常多&#xff0c;我只是按照我的理解列出了性能优化整个过程中需要考虑的种种因素。点到为止&#xff0c;包含的内容以浅显的介绍为主&#xff0c;如果你有见解能告知我那再好不…

PYTHON 爬虫笔记十一:Scrapy框架的基本使用

Scrapy框架详解及其基本使用 scrapy框架原理 Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架。 其可以应用在数据挖掘&#xff0c;信息处理或存储历史数据等一系列的程序中。其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的&#xff0c; 也可…

服务器返回值 解释 ajax提交方式 后台数据刷进前端

转载于:https://www.cnblogs.com/liuliang389897172/p/9120715.html

no typehandler found for property XXXX 解决

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. ssm框架下 启动服务报错如题。 2. 原因&#xff1a; 我的情况是&#xff0c;代码中实体属性映射书写和数据库字段名字不一致。 数据…

shell中sed -i特殊字符

可参考文献&#xff1a; Linux生产环境上&#xff0c;最常用的一套“sed“技巧 看懂shell中的各种语句