对象和变量的并发访问synchronized解析以及死锁分析排查
/**
* @author monkjavaer
* @date 2018/11/26 21:12
*/
public class Service2 {
/**
* 同步方法
*/
public synchronized void printService() {
System.out.println(Thread.currentThread().getName() + " " + "start printService thread");
try {
TimeUnit.MILLISECONDS.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + "printService end ");
} /**
* 同步方法
*/
public synchronized void printServiceOther() {
System.out.println(Thread.currentThread().getName() + " " + "start printServiceOther thread");
try {
TimeUnit.MILLISECONDS.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + "printServiceOther end ");
} /**
* 非同步方法
*/
public void printServiceNotSynchronized() {
System.out.println(Thread.currentThread().getName() + " " + "start printServiceNotSynchronized thread");
try {
TimeUnit.MILLISECONDS.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + "printServiceNotSynchronized end ");
}
}
线程A:
public class Syn2ThreadA extends Thread{
private Service2 service;
public Syn2ThreadA(Service2 service) {
this.service = service;
}
@Override
public void run() {
super.run();
service.printService();
}
}
线程B:
public class Syn2ThreadB extends Thread{
private Service2 service;
public Syn2ThreadB(Service2 service) {
this.service = service;
}
@Override
public void run() {
super.run();
service.printServiceNotSynchronized();
}
}
线程C:
public class Syn2ThreadC extends Thread{
private Service2 service;
public Syn2ThreadC(Service2 service) {
this.service = service;
}
@Override
public void run() {
super.run();
service.printServiceOther();
}
}
测试方法:
public class Syn2Test {
public static void main(String[] args) {
Service2 service = new Service2();
//Syn2ThreadA调用了同步方法
Syn2ThreadA threadA = new Syn2ThreadA(service);
threadA.setName("threadA");
//Syn2ThreadB调用非同步
Syn2ThreadB threadB = new Syn2ThreadB(service);
threadB.setName("threadB");
//Syn2ThreadC调用了同步方法
Syn2ThreadC threadC = new Syn2ThreadC(service);
threadC.setName("threadC");
threadA.start();
threadB.start();
threadC.start();
}
}
可通过执行上面代码通过程序输出顺序证明以上结论的正确性。
public class Fruit {
public synchronized void dosomething(){
System.out.println("printFruit");
}
}
子类:
public class Apple extends Fruit {
@Override
public synchronized void dosomething() {
super.dosomething();
System.out.println("apple");
}
}
3.死锁
那什么是死锁呢? 下面是维基百科对死锁的定义:

编码证明:
/**
* @author monkjavaer
* @date 2018/11/26 22:37
*/
public class TestDeadlock { static final String resource1 = "resource1";
static final String resource2 = "resource2"; static class ThreadA extends Thread {
@Override
public void run() {
synchronized (resource1) {
System.out.println("ThreadA: locked resource 1");
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource2) {
System.out.println("ThreadA: locked resource 2");
}
}
}
} static class ThreadB extends Thread {
@Override
public void run() {
synchronized (resource2) {
System.out.println("ThreadB: locked resource 2");
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource1) {
System.out.println("ThreadB: locked resource 1");
}
}
}
} public static void main(String[] args) {
ThreadA threadA = new ThreadA();
threadA.setName("====ThreadA====");
ThreadB threadB = new ThreadB();
threadB.setName("====ThreadB====");
threadA.start();
threadB.start();
}
}
上面的代码运行时会产生死锁情况。
4.追踪、分析死锁发生


a、synchronized同步方法弊端:如果一个线程调用同步方法要执行很长时间,那么其他线程要调用这个同步方法必须等待很长时间。
可以用synchronized解决,不在synchronized块中的代码异步执行。并且synchronized块synchronized方法是一样的使用的对象监视器是一个,他们都是锁定的当前对象。
b、synchronized同步不能被继承。
c、synchronized加到静态方法上时是给class类上锁,加到非静态方法是给对象上锁。
d、一般synchronized块不用String作为锁对象,因为String常量池有缓存功能。导致锁对象可能一直是相同的。
String a = "a";
String b = "a";
System.out.println(a==b);
比如上面的代码得到的结果是true
对象和变量的并发访问synchronized解析以及死锁分析排查的更多相关文章
- (二)对象以及变量的并发访问--synchronized的使用细节,用法
具体的记录synchronized关键的各种使用方式,注意事项.感觉一步一步跟我来都可以看懂滴 大致是按照以下思路进行书写的.黑体字可以理解为结论, 1.synchronized锁的是什么? 2.sy ...
- Java多线程编程核心技术-第2章-对象及变量的并发访问-读书笔记
第 2 章 对象及变量的并发访问 本章主要内容 synchronized 对象监视器为 Object 时的使用. synchronized 对象监视器为 Class 时的使用. 非线程安全是如何出现的 ...
- Java多线程编程核心技术---对象及变量的并发访问(一)
synchronized同步方法 "非线程安全"其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是"脏读",也就是渠道的数据其实是被更改 ...
- Java多线程编程核心技术(二)对象及变量的并发访问
本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...
- 对象及变量的并发访问(同步方法、同步代码块、对class进行加锁、线程死锁)&内部类的基本用法
主要学习多线程的并发访问,也就是使得线程安全. 同步的单词为synchronized,异步的单词为asynchronized 同步主要就是通过锁的方式实现,一种就是隐式锁,另一种是显示锁Lock,本节 ...
- Java多线程编程核心 - 对象及变量的并发访问
1.什么是“线程安全”与“非线程安全”? “非线程安全”会在多个线程对同一对象总的实例变量进行并发访问时发生,产生的后果是“脏读”,也就是取到的数据其实是被更改过的. “线程安全”是以获得的实例变量的 ...
- Java多线程——对象及变量的并发访问
Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...
- Java——多线程之对象及变量的并发访问
Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...
- 《JAVA多线程编程核心技术》 笔记:第二章:对象及变量的并发访问
一.基本概念1.安全的变量和不安全的变量2.脏读的理解3.锁重入:4.锁释放5.死循环:二.synchronized 的理解:三.synchronized 同步方法3.1 同步方法不具有继承性.3.2 ...
随机推荐
- 思维题 HDOJ 5288 OO’s Sequence
题目传送门 /* 定义两个数组,l[i]和r[i]表示第i个数左侧右侧接近它且值是a[i]因子的位置, 第i个数被选择后贡献的值是(r[i]-i)*(i-l[i]),每个数都枚举它的因子,更新l[i] ...
- TCP/IP与Http与socket的关系
1 理清概念: TCP/IP是一个大的协议族(只不过TCP和IP是super star所以就这么命名了),它包括了: 应用层协议:FTP.HTTP.TELNET.SMTP.DNS(协议): 传输层协议 ...
- kafka_2.11-0.8.2.2.tgz的3节点集群的下载、安装和配置(图文详解)
kafka_2.10-0.8.1.1.tgz的1或3节点集群的下载.安装和配置(图文详细教程)绝对干货 一.安装前准备 1.1 示例机器 二. JDK7 安装 1.1 下载地址 下载地址: http: ...
- Spring Boot (32) Lock 本地锁
平时开发中,有时会双击提交表单造成重复提交,或者网速比较慢时还没有响应又点击了按钮,我们在开发中必须防止重复提交 一般在前台进行处理,定义个变量,发送请求前判断变量值为true,然后把变量设置为fal ...
- Linux shell命令之cat
cat:查看文件的内容.连接文件.创建一个或多个文件和重定向输出到终端或文件 用法:cat [选项] [文件] 1. $ cat hello.txt 显示hello.txt文本文件中的内容 2. $ ...
- [ CCO 2015 ] Artskjid
\(\\\) \(Description\) \(N\)个点\(M\)条边的有向图,求从\(0\)号节点出发,\(N-1\)号节点结束,且图中每个点至多经过一次的最长路. \(N\in[2,18]\) ...
- cocos2d-x android 环境部署
1.下载jdk http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2.下载 and ...
- firefox浏览器中 bootstrap 静态弹出框中select下拉框不能弹出(解决方案)
问题出现场景1: 在firefox浏览器中在bootstrap弹出的modal静态框中再次弹出一个静态框时 select下拉框不能弹出选项 解决方案:去掉最外层静态框的 tabindex=" ...
- (转) 淘淘商城系列——redis-desktop-manager的使用
http://blog.csdn.net/yerenyuan_pku/article/details/72849791 实际工作环境中,redis会安装在服务器上,我们想使用redis服务就要使用re ...
- PHP爬数据 QueryList
QueryList官方文档:https://www.querylist.cc/docs/guide/v3 因为php版本使用5.6,所以使用QueryList v3版本,php7可以使用 v4版本 v ...