学习笔记:java线程安全
class Thread2 extends Thread{
public void run() {
MyObj obj = new MyObj();
try {
obj.sayHello(3000);//3秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} class Thread3 extends Thread{
public void run() {
MyObj obj = new MyObj();
try {
obj.sayHello(1000);//1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} class MyObj {
public synchronized void sayHello(int delay) throws InterruptedException{
Thread.sleep(delay);
System.out.println("delay" + delay);
}
}
public class ThreadTest {
public static void main(String[] args) throws Exception{
Thread2 t2 = new Thread2();
Thread3 t3 = new Thread3();
t2.start();//先让t2线程启动,因为t2要等待3秒,如果线程同步有作用的话t3会处理阻塞状态
t3.start();
}
}
代码中的MyObj类就是我用于测试的线程安全的对象,它包含了一个sayHello方法,他是带有synchronized关键字的。但测试结果却是
delay1000
delay3000
这说明关键字没有起作用,也说明了不同的对象实例synchronized方法时是线程不安全的。知道这个结果心里有些难过,只不过事情已经过去就当是学习了经验吧。
synchronized除了修饰方法外,还可以修饰代码块,那就试试看吧,写了一个新的类:
class MyObj2 {
private static Object lockObj = new Object();
public void sayHello(int delay) throws InterruptedException{
synchronized(lockObj){
Thread.sleep(delay);
System.out.println("delay" + delay);
}
}
}
用这个类做测试的结果:
delay3000
delay1000
这说明synchronized修改代码块时线程同步是起作用的,但这里要注意,采用synchronized代码块时,synchronized(lockObj)中的lockObj对象是一个静态对象,所以他们对应的锁是同一个,这就可以实现线程间的同步。如果换成synchronized(this)又无法同步。
于是就得想明白为什么会有这两种差别呢?原来JAVA中每个对象都对应一个锁,synchronized关键字是通过检查这个对象锁的状态来调度的。这下就明白了,原来关键就在于对象对应的那个锁,MyObj之所以不能同步是因为创建了两不同的对象实例,自然对应的对象锁就不同,而synchronized修饰的是方法时,其对应检查的是当前对象的锁,所以就会出现不同步的情况。
后来在网上查资料的同时也发现一个叫类锁的东东,通过类锁获得的类本身,是唯一的,那么就应该是可以同步了,代码如下:
class MyObj3 {
public synchronized static void sayHello(int delay) throws InterruptedException{
Thread.sleep(delay);
System.out.println("delay" + delay);
}
}
得到的结果
delay3000
delay1000
这说明已经同步了,synchronized+static一起修改时获得的是类锁,获得类本身,所以只有一个,那么同步自然有了效果。
注:“光之子”在评论中指出了本文的一些问题,有兴趣的朋友看到本文请把评论也看看吧。
学习笔记:java线程安全的更多相关文章
- java学习笔记15--多线程编程基础2
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...
- JUC源码学习笔记5——线程池,FutureTask,Executor框架源码解析
JUC源码学习笔记5--线程池,FutureTask,Executor框架源码解析 源码基于JDK8 参考了美团技术博客 https://tech.meituan.com/2020/04/02/jav ...
- [java学习笔记]java语言核心----面向对象之this关键字
一.this关键字 体现:当成员变量和函数的局部变量重名时,可以使用this关键字来区别:在构造函数中调用其它构造函数 原理: 代表的是当前对象. this就是所在函数 ...
- [java学习笔记]java语言核心----面向对象之构造函数
1.构造函数概念 特点: 函数名与类名相同 不用定义返回值类型 没有具体的返回值 作用: 给对象进行初始化 注意: 默认构造函数 多个构造函数是以重载出现的 一个类中如果 ...
- 操作系统学习笔记----进程/线程模型----Coursera课程笔记
操作系统学习笔记----进程/线程模型----Coursera课程笔记 进程/线程模型 0. 概述 0.1 进程模型 多道程序设计 进程的概念.进程控制块 进程状态及转换.进程队列 进程控制----进 ...
- java学习笔记14--多线程编程基础1
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为 ...
- java学习笔记之线程(Thread)
刚开始接触java多线程的时候,我觉得,应该像其他章节的内容一样,了解了生命周期.构造方法.方法.属性.使用的条件,就可以结束了,然而随着我的深入学习了解,我发现java的多线程是java的一个特别重 ...
- (Java学习笔记) Java Threading (Java线程)
Java Threading (Java线程) ● Process & Thread Processes are the abstraction of running programs: A ...
- JavaSE中线程与并行API框架学习笔记1——线程是什么?
前言:虽然工作了三年,但是几乎没有使用到多线程之类的内容.这其实是工作与学习的矛盾.我们在公司上班,很多时候都只是在处理业务代码,很少接触底层技术. 可是你不可能一辈子都写业务代码,而且跳槽之后新单位 ...
- Java学习笔记 -- Java定时调度工具Timer类
1 关于 (时间宝贵的小姐姐请跳过) 本教程是基于Java定时任务调度工具详解之Timer篇的学习笔记. 什么是定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. 在Ja ...
随机推荐
- javascript 转盘抽奖代码和计数器代码
要介绍了javascript圆盘抽奖程序实现原理和完整代码例子,需要的朋友可以参考下 看到网页上有不少大转盘抽奖的应用,心血来潮也想弄个.于是找了点资料自己研究... 效果预览: 一.模拟抽奖的实 ...
- Range Sum Query 2D - Immutable
https://leetcode.com/problems/range-sum-query-2d-immutable/ 条件说sumRegion 会调很多次,如果每次都用双for 循环去累加的话就有太 ...
- Chrome Extension 检查视图(无效)处理方法
最近闲来无事,简单看了下Chrome扩展的开发,并且开发一个小小的翻译插件(TranslateBao)作为练手,开发细节不详述了,如果有新学习chrome extension开发的新人,可以参考源码, ...
- [译]:Xamarin.Android开发入门——Hello,Android Multiscreen深入理解
原文链接:Hello, Android Multiscreen_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android Multiscreen深入理解. 本 ...
- app后端设计--总目录 (转)
特此说明,我转载的!!! app后端设计(1)--api app后端设计(2)--xmpp的使用 app后端设计(3)--短信,邮件,推送服务 app后端设计(4)-- 通讯的安全性 app后端设计( ...
- 获取html 中的内容 将前台的数据获取到后台
使用js创建一个form表单 ,使用post上传到后台中 下面是代码.在获取html内容的时候使用了js节点来获取内容. parent:父节点.上一级的节点 siblings:兄弟节点.同一级别的节点 ...
- 搜索技巧<转>
平时工作,搜索引擎是少不了的,作为程序员,当然首推 Google.这里简单介绍下几个 Google 搜索的小技巧,方便别人也方便自己查阅. ps:以下所有操作,均可以在 「谷歌搜索首页 -> 设 ...
- java-并发-同步
浏览以下内容前,请点击并阅读 声明 线程间的通信主要是通过访问以及对象引用字段,这种形式的通信非常高效,但是会产生两种可能的错误:线程干扰和内存一致性错误,反正这些错误的工具就是同步. 然而,同步可能 ...
- RNN求解过程推导与实现
RNN求解过程推导与实现 RNN LSTM BPTT matlab code opencv code BPTT,Back Propagation Through Time. 首先来看看怎么处理RNN. ...
- java 通过jdbc连接MySQL数据库
先了解下JDBC的常用接口 1.驱动程序接口Driver 每种数据库的驱动程序都应该提供一个实现java.sql.Driver接口的类,简称Driver类.通常情况下,通过java.lang.Clas ...