四、java多线程核心技术——synchronized同步方法与synchronized同步快
一、synchronized同步方法
论:“线程安全”与“非线程安全”是多线程的经典问题。synchronized()方法就是解决非线程安全的。
1、方法内的变量为线程安全
public void addI(String username) {
try {
int num = 0; \\方法内的变量为线程安全
if (username.equals("a")) {
num = 100;
System.out.println("a set over!");
Thread.sleep(2000);
} else {
num = 200;
System.out.println("b set over!");
}
System.out.println(username + " num=" + num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2、实例变量非线程安全
public class HasSelfPrivateNum {
private int num = 0; \\实例变量非线程安全
public void addI(String username) {
try {
if (username.equals("a")) {
num = 100;
System.out.println("a set over!");
Thread.sleep(2000);
} else {
num = 200;
System.out.println("b set over!");
}
System.out.println(username + " num=" + num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
解决方法: 方法前加synchronized关键字。
public class HasSelfPrivateNum { private int num = 0; synchronized public void addI(String username) {
..............
} }
3、多个对象多个锁
HasSelfPrivateNum.java
public class HasSelfPrivateNum { private int num = 0; synchronized public void addI(String username) {
try {
if (username.equals("a")) {
num = 100;
System.out.println("a set over!");
Thread.sleep(2000);
} else {
num = 200;
System.out.println("b set over!");
}
System.out.println(username + " num=" + num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
ThreadA
public class ThreadA extends Thread { private HasSelfPrivateNum numRef; public ThreadA(HasSelfPrivateNum numRef) {
super();
this.numRef = numRef;
} @Override
public void run() {
super.run();
numRef.addI("a");
} }
ThreadB
public class ThreadB extends Thread { private HasSelfPrivateNum numRef; public ThreadB(HasSelfPrivateNum numRef) {
super();
this.numRef = numRef;
} @Override
public void run() {
super.run();
numRef.addI("b");
} }
RUN
public class Run { public static void main(String[] args) { HasSelfPrivateNum numRef1 = new HasSelfPrivateNum();
HasSelfPrivateNum numRef2 = new HasSelfPrivateNum(); ThreadA athread = new ThreadA(numRef1);
athread.start(); ThreadB bthread = new ThreadB(numRef2);
bthread.start(); } }
结果:创建了2个业务实例,产生2个锁,所以运行结果是异步的。同步为synchronized 异步:asynchronized
4、synchronized 锁重入
当一个线程得到一个对象锁时,再次请求该对象锁时是可以再次得到该对象的锁的。继承关系也可重入锁。
当一个线程执行发生异常时,其持有的锁会自动释放。
同步不具有继承性。的在子类方法中添加synchronized的关键字。
public class HasSelfPrivateNum {
synchronized public void service1() {
System.out.println("service1");
service2();
} synchronized public void service2() {
System.out.println("service2");
service3();
} synchronized public void service3() {
System.out.println("service3");
}
}
HasSelfPrivateNum.java
public class mYThread extends Thread {
@Override
public void run() {
HasSelfPrivateNum hspn=new HasSelfPrivateNum();
hspn.service1();
}
public static void main(String[] args) {
mYThread mYThread=new mYThread();
mYThread.start();
}
}
mYThread.java
二、synchronized同步快
synchronized同步方法持有锁后,如果长时间不释放,那另一个线程就必须长时间等待。。这种情况下synchronized同步快来解决
使用方法如图:
1、synchronized同步快之间具有同步性,当线程访问object的一个 synchronized(this)同步代码块时,其他线程对同一个object对象中所有其他的
synchronized(this)同步代码块的访问会被阻塞。
2、synchronized(this)同步代码块是锁定当前对象的。
1、synchronized同步快解决同步方法效率低得弊端
public class Task { private String getData1;
private String getData2; public synchronized void doLongTimeTask() {
try {
System.out.println("begin task");
Thread.sleep(3000);
getData1 = "长时间处理任务后从远程返回的值1 threadName="
+ Thread.currentThread().getName();
getData2 = "长时间处理任务后从远程返回的值2 threadName="
+ Thread.currentThread().getName();
System.out.println(getData1);
System.out.println(getData2);
System.out.println("end task");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Task
public class MyThread1 extends Thread { private Task task; public MyThread1(Task task) {
super();
this.task = task;
} @Override
public void run() {
super.run();
CommonUtils.beginTime1 = System.currentTimeMillis();
task.doLongTimeTask();
CommonUtils.endTime1 = System.currentTimeMillis();
} }
MyThread1
public class MyThread2 extends Thread { private Task task; public MyThread2(Task task) {
super();
this.task = task;
} @Override
public void run() {
super.run();
CommonUtils.beginTime2 = System.currentTimeMillis();
task.doLongTimeTask();
CommonUtils.endTime2 = System.currentTimeMillis();
} }
MyThread2
public class CommonUtils { public static long beginTime1;
public static long endTime1; public static long beginTime2;
public static long endTime2;
}
CommonUtils
public class Run { public static void main(String[] args) {
Task task = new Task(); MyThread1 thread1 = new MyThread1(task);
thread1.start(); MyThread2 thread2 = new MyThread2(task);
thread2.start(); try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
} long beginTime = CommonUtils.beginTime1;
if (CommonUtils.beginTime2 < CommonUtils.beginTime1) {
beginTime = CommonUtils.beginTime2;
} long endTime = CommonUtils.endTime1;
if (CommonUtils.endTime2 > CommonUtils.endTime1) {
endTime = CommonUtils.endTime2;
} System.out.println("耗时:" + ((endTime - beginTime) / 1000));
}
}
Run
修改Task
public class Task { private String getData1;
private String getData2; public void doLongTimeTask() {
try {
System.out.println("begin task");
Thread.sleep(3000); String privateGetData1 = "长时间处理任务后从远程返回的值1 threadName="
+ Thread.currentThread().getName();
String privateGetData2 = "长时间处理任务后从远程返回的值2 threadName="
+ Thread.currentThread().getName(); synchronized (this) {
getData1 = privateGetData1;
getData2 = privateGetData2;
} System.out.println(getData1);
System.out.println(getData2);
System.out.println("end task");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
四、java多线程核心技术——synchronized同步方法与synchronized同步快的更多相关文章
- Java多线程学习(二)synchronized关键字(2)
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java多线程学习(二)synchronized关键字(1)
转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...
- Java多线程核心技术(四)Lock的使用
本文主要介绍使用Java5中Lock对象也能实现同步的效果,而且在使用上更加方便. 本文着重掌握如下2个知识点: ReentrantLock 类的使用. ReentrantReadWriteLock ...
- Java多线程(三):Synchronized
多线程安全 脏读:多个线程对同一个对象的实例变量进行修改后访问,导致读到的数据是被修改过的. 实例 ThreadDomain16类 public class ThreadDomain16 { priv ...
- “全栈2019”Java多线程第十六章:同步synchronized关键字详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Java多线程核心技术(五)单例模式与多线程
本文只需要考虑一件事:如何使单例模式遇到多线程是安全的.正确的 1.立即加载 / "饿汉模式" 什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就是直接 ...
- 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)
本文分析了HashMap的实现原理,以及resize可能引起死循环和Fast-fail等线程不安全行为.同时结合源码从数据结构,寻址方式,同步方式,计算size等角度分析了JDK 1.7和JDK 1. ...
- 160711、Java 多线程核心技术梳理
本文对多线程基础知识进行梳理,主要包括多线程的基本使用,对象及变量的并发访问,线程间通信,lock 的使用,定时器,单例模式,以及线程状态与线程组. java 多线程 基础知识 创建线程的两种方式:1 ...
- Java多线程核心技术(六)线程组与线程异常
本文应注重掌握如下知识点: 线程组的使用 如何切换线程状态 SimpleDataFormat 类与多线程的解决办法 如何处理线程的异常 1.线程的状态 线程对象在不同运行时期有不同的状态,状态信息就处 ...
- Java 多线程基础(五)线程同步
Java 多线程基础(五)线程同步 当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题. 要解决上述多线程并发访问一个资源的安全性问题,Java中提供了同步机制 ...
随机推荐
- centos8 连接wifi
从官网下载的6G多的iso安装后 #ifconfig -a 如下 enp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500l ...
- Guitar Pro怎么导出乐谱
使用Guitar Pro可以自由创作乐谱,也能根据演示效果来作出相应调整,算得上是公认的良心吉他谱制作软件.除了系统演示功能外,Guitar Pro还能给用户的实际练习提供便利.必要时,用户能将软件内 ...
- go学习路线资料
编辑器 JetBrains公司出品的,goland go初步学习路线 Go 指南 如何使用Go编程 实效Go编程 Go by Example 中文版 参考: Go 语言学习资料与社区索引 Go入门指南 ...
- Redis设计与实现一之简单的动态字符串
简单的动态字符串 Redis没有直接使用C语言中的字符串,而是自己构建了SDS这样的一种简单动态字符串,并且将他作为Redis中字符串的默认的表示. 但是并未完全抛弃C语言字符串,只不过是在C语言字符 ...
- Maven更换阿里源与仓库地址
一.为什么要更换maven中的阿里源和仓库地址? 因为咱们下载安装的maven默认配置的源的服务器在国外,所以对于咱们来说,下载jar包的速度会很慢,所以咱们要把它替换为咱们国内的,可以换成好多,如华 ...
- C语言讲义——链表的实现
节点(结构体描述) struct Node { int _id; char s[50]; struct Node* pre;// 指向前一个节点的地址 struct Node* next;// 指向下 ...
- Java基础教程——System类
System类 java.lang.System类代表当前Java程序的运行平台. |-可以做输入输出,垃圾回收:(此处不讲) |-可以获取时间: |-可以获取环境变量: |-可以获取系统信息: |- ...
- C语言是如何诞生的?地位怎样?未来发展趋势?
C语言的历史 C语言的原型是A语言(ALGOL 60语言). 1963年,剑桥大学将ALGOL 60语言发展成为CPL(Combined Programming Language)语言. 1967 ...
- HEXO | 给博客添加RSS
Hexo是一个简洁.高效.易用的博客框架,同时它拥有十分丰富的主题环境,本次我们所谈到的是cards主题,但是该主题的原生环境里没有相关的rss配置,所以我们需要采用手动添加的方式,进而实现rss功能 ...
- 记一次腾讯TBS浏览服务集成实践
这次的分享源于最近的实际开发工作. 项目需求是 在原生Android应用中嵌入WebView,放置用于支撑音视频直播业务的Web页: 另外还需提供Word.Excel.PowerPoint.PDF等常 ...