学习笔记: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 ...
随机推荐
- ExtJS基础知识总结:自定义日历和ComboBox控件(二)
概述 1.ExtJS 5不支持日期选择框中只选择年月,为了满足ExtJs5可以实现选择年月的功能,查询网上资料,整理出来了相应的处理方式,最终实现的效果如下图: 2.ExtJS 控件丰富,如果需要实现 ...
- ORACLE序列号
select MAXSYSACCEPT.nextval from dual; (序列号检索 增1)alter sequence MAXSYSACCEPT increment by 1 cache 20 ...
- CPU状态信息us,sy,ni,id,wa,hi,si,st含义
转自:http://blog.csdn.net/sasoritattoo/article/details/9318893 转自:http://fishermen.iteye.com/blog/1995 ...
- Mvc HtmlHelper 方法扩展 DropDownListFor
项目中遇到表单提交中遇到枚举,忽然想起1年前的1小段代码结合HtmlHelper在扩展一下 便于开发中使用 public static class HtmlHelperExtensions { p ...
- 对Raphael画图标的一个jquery简单封装
公司要做一个项目的demo,要求地图上可以插红旗,所以就用到了Raphael. 因为是个demo,所以地图就用了一张图片,效果如下: 所以为了更好的封装一下这个功能,就写了一个简单的插件:jquery ...
- #英文#品读中国城市个性——秦汉雄风&和祖先在一起
妨碍 interfere with 仇恨 hatred 坍塌 collapse 专制君主 autocratic dictator 排除异己 suppress opposition 被逼到绝望边缘 b ...
- 追踪记录每笔业务操作数据改变的利器——SQLCDC
对于大部分企业应用来用,有一个基本的功能必不可少,那就是Audit Trail或者Audit Log,中文翻译为追踪检查.审核检查或者审核记录.我们采用Audit Trail记录每一笔业务操作的基本信 ...
- BZOJ 3262 陌上花开 ——CDQ分治
[题目分析] 多维问题,我们可以按照其中一维排序,然后把这一维抽象的改为时间. 然后剩下两维,就像简单题那样,排序一维,树状数组一维,按照时间分治即可. 挺有套路的一种算法. 时间的抽象很巧妙. 同种 ...
- DirectX9 Sample_Empty Project
作为第一个程序,EmpytProject仅仅示范了如何绑定DXUTstate结构中的回调函数. 回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当 ...
- Visual Studio 常用快捷键
作为一个使用VisualStudio的程序员,使用快捷键会为你的开发提供助力. 下附个人开发过程中感觉比较实用的快捷键: 开始运行"devenv",启动相应版本的VisualStu ...