在 Java 的多线程中,如何去判断给定的一个类是否是线程安全的(另外:synchronized 同步是否就一定能保证该类是线程安全的。)
同步代码块和同步方法的区别:同步代码块可以传入任意对象,同步方法中 如果多个线程检查的都是一个新的对象,不同的同步锁对不同的线程不具有排他性,不能实现线程同步的效果,这时候线程同步就失效了。
两者的区别主要体现在同步锁上面。对于实例的同步方法,因为只能使用this来作为同步锁,如果一个类中需要使用到多个锁,为了避免锁的冲突,必然需要使用不同的对象,这时候同步方法不能满足需求,只能使用同步代码块(同步代码块可以传入任意对象);
有几个原则的:
程序次序规则:一个线程内,代码的执行会按照程序书写的顺序
管程锁定原则:对同一变量的unlock操作先行发生于后来的lock操作
volatile变量规则:对一个volatile的写操作先行发生于后来的读操作
线程启动原则:Thread的start()先行发生于线程内的所有动作
线程终止原则:线程内的所有动作都先行发生于线程的终止检测
线程中断原则:对线程调用interrupt()先行发生于被中断的代码检测到是否有中断发生
对象终结原则:一个对象的初始化操作先行发生于finalize()方法
传递性:A先行发生于B,B先行发生于C,那么A先行发生于C
Java多线程编程总结
http://lavasoft.blog.51cto.com/62575/27069
/**
* Java线程:并发协作-死锁
*
* @author Administrator 2009-11-4 22:06:13
*/
public class Test {
public static void main(String[] args) {
DeadlockRisk dead = new DeadlockRisk();
MyThread t1 = new MyThread(dead, 1, 2);
MyThread t2 = new MyThread(dead, 3, 4);
MyThread t3 = new MyThread(dead, 5, 6);
MyThread t4 = new MyThread(dead, 7, 8);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class MyThread extends Thread {
private DeadlockRisk dead;
private int a, b;
MyThread(DeadlockRisk dead, int a, int b) {
this.dead = dead;
this.a = a;
this.b = b;
}
@Override
public void run() {
dead.read();
dead.write(a, b);
}
}
class DeadlockRisk {
private static class Resource {
public int value;
}
private Resource resourceA = new Resource();
private Resource resourceB = new Resource();
public int read() {
synchronized (resourceA) {
System.out.println("read():" + Thread.currentThread().getName() + "获取了resourceA的锁!");
synchronized (resourceB) {
System.out.println("read():" + Thread.currentThread().getName() + "获取了resourceB的锁!");
return resourceB.value + resourceA.value;
}
}
}
public void write(int a, int b) {
synchronized (resourceB) {
System.out.println("write():" + Thread.currentThread().getName() + "获取了resourceA的锁!");
synchronized (resourceA) {
System.out.println("write():" + Thread.currentThread().getName() + "获取了resourceB的锁!");
resourceA.value = a;
resourceB.value = b;
}
}
}
}

在 Java 的多线程中,如何去判断给定的一个类是否是线程安全的(另外:synchronized 同步是否就一定能保证该类是线程安全的。)的更多相关文章
- Java日期时间API系列8-----Jdk8中java.time包中的新的日期时间API类的LocalDate源码分析
目录 0.前言 1.TemporalAccessor源码 2.Temporal源码 3.TemporalAdjuster源码 4.ChronoLocalDate源码 5.LocalDate源码 6.总 ...
- 一个".java"的源文件中,是否可以包含多个类?(除了匿名内部类),有什么限制?
# 二.一个".java"的源文件中,是否可以包含多个类?(除了匿名内部类),有什么限制? - 可以包含多个类 - 条件:其它类不能用private.public.prot ...
- Java日期时间API系列13-----Jdk8中java.time包中的新的日期时间API类,时间类转换,Date转LocalDateTime,LocalDateTime转Date等
从前面的系列博客中可以看出Jdk8中java.time包中的新的日期时间API类设计的很好,但Date由于使用仍非常广泛,这就涉及到Date转LocalDateTime,LocalDateTime转D ...
- Java日期时间API系列19-----Jdk8中java.time包中的新的日期时间API类,ZonedDateTime与ZoneId和LocalDateTime的关系,ZonedDateTime格式化和时区转换等。
通过Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类中时间范围示意图:可以很清晰的看出ZonedDateTime相当于LocalDateTime+ZoneI ...
- Java日期时间API系列11-----Jdk8中java.time包中的新的日期时间API类,使用java8日期时间API重写农历LunarDate
通过Java日期时间API系列7-----Jdk8中java.time包中的新的日期时间API类的优点,java8具有很多优点,现在网上查到的农历转换工具类都是基于jdk7及以前的类写的,下面使用ja ...
- Java日期时间API系列12-----Jdk8中java.time包中的新的日期时间API类,日期格式化,常用日期格式大全
通过Java日期时间API系列10-----Jdk8中java.time包中的新的日期时间API类的DateTimeFormatter, 可以看出java8的DateTimeFormatter完美解决 ...
- Java:多线程中的volatile
一.为什么使用volatile 首先,通过一段简单的代码来理解为什么要使用volatile: public class RunThread extends Thread{ private boolea ...
- Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类
因为Jdk7及以前的日期时间类的不方便使用问题和线程安全问题等问题,2005年,Stephen Colebourne创建了Joda-Time库,作为替代的日期和时间API.Stephen向JCP提交了 ...
- Java日志框架中真的需要判断log.isDebugEnabled()吗?
在项目中我们经常可以看到这样的代码: if (logger.isDebugEnabled()) { logger.debug(message); } 简单来说,就是用isDebugEnabled方法判 ...
随机推荐
- 配置Nginx四层负载均衡
nginx 支持TCP转发和负载均衡的支持 实现下面的架构: 看配置: #user nobody; worker_processes 1; #error_log logs/error.log; #er ...
- 报错:'Navigator is deprecated and has been removed from this package. It can now be installed
报错:'Navigator is deprecated and has been removed from this package. It can now be installed ' + ...
- js里=、== 和===有什么区别?
说明:该文章是转载后进行修改完善的,望大家有收获. =是赋值运算符,==是关系运算符; ===是全等运算符. ”==”与”===”是不同的,一个是判断值是否相等,一个是判断值及类型是否完全相等.第一个 ...
- fatal error C1902: 程序数据库管理器不匹配;请检查安装解决
http://blog.sina.com.cn/s/blog_9f4bc8e301015uhz.html 1.错误提示:VS2008编译错误fatal error C1902: 程序数据库管理器不匹配 ...
- DDD领域驱动之干货 (一)
说道DDD不得不说传统的架构与DDD的架构区别. 传统的架构不外乎就是三层,而在这三层里面又不断的细分,始终没有达到想要的效果,那么为什么当时还是采用三层. 当然在DDD没有提出的时候三层是大多数人的 ...
- P1816 忠诚
题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了 ...
- css3计算属性(calc)
如果有固定头部高度和底部高度,内容的高度或者宽度想要根据浏览器屏幕自适应的话,可以用到css3的计算属性,即calc. 用法如下: 内容区域高/宽 = calc(100% - 头部高宽 - 底部高宽) ...
- Json 不同语言的使用
Javascript: 1.使用eval var parse_json_by_eval = function(str){ return eval('('+str+')'); } var value = ...
- PICO SCOPE 3000 Series 示波器
- java 内存管理机制
垃圾收集算法 1.标记清理算法:效率不高(标记和清理过程效率都不高).会形成内存碎片 2.复制算法:把内存分为两部分,当进行回收时,把使用部分的存活对象复制到未使用部分,然后两部分内存角色互换(一个为 ...