线程系列2--Java线程的互斥技术
java的多线程互斥主要通过synchronized关键字实现。一个线程就是一个执行线索,多个线程可理解为多个执行线索。进程有独立的内存空间,而进程中的线程则是共享数据对象资源。这样当多个执行线索在CPU的切换下交替执行,就会出现一些恶心的情况,执行的结果也是匪夷所思。第一个线程未执行完,CPU切换到另一个线程执行,由于数据资源共享,将导致程序的执行混乱。解决线程间的互斥主要就是通过synchronized来实现。
下面利用传智播客里面的代码举例分析:
package com.cqfczc.util;
/**
* 多线程的互斥技术
* @author zhenliang
*
*/
public class ThreadSynchronized {
public static void main(String[] args) {
new ThreadSynchronized().testThread();
}
private void testThread(){
final OutPutPrinter printer = new OutPutPrinter();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
printer.printer("风铃三世爱着猴子");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
printer.printer("猴子始终喜欢杨婵");
}
}
}).start();
}
//多线程不适用互斥技术时的有问题代码
class OutPutPrinter{
public void printer(String name){
if(name == null){
throw new NullPointerException("参数不能为空!");
}
int nameLength = name.length();
for(int i=0;i<nameLength;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
1、自定义的对象作为锁对象
实现方式 :synchronized(<自定义锁对象>){…}
适用情况:当出现需要在多个类(或者多个类的实例)之间进行互斥控制时,需要采用本方法。
class OutPutPrinter{
private String lock = "大泼猴";
public void printer(String name){
if(name == null){
throw new NullPointerException("参数不能为空!");
}
int nameLength = name.length();
synchronized(lock){
for(int i=0;i<nameLength;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
2、以this作为锁对象
实现方式:synchronized(this){…},synchronized实例方法;
适用情况:适用于使用类的同一个实例(对象)作为锁对象。
// 同步方法,相当于synchronized(this){}
public synchronized void output2(String name) {
int len = name.length();
for(int i=0; i<len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
3、以Outputer.class作为锁对象
Outputer类的字节码对象由jvm自动加载。
实现方式:synchronized(Outputer.class){…} ,static synchronized方法
适用情况:适用于整个类的所有对象都需要互斥访问的情况
// 静态同步方法,相当于synchronized(Outputer.class){}
public static synchronized void output3(String name) {
int len = name.length();
for(int i=0; i<len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
总结:同一个类中代码块或者方法的互斥,使用this或者类的字节码作为对象锁;当需要在多个类(或者多个类的实例)之间进行互斥控制时,使用自定义对象锁或类字节码对象锁;因为类的字节码全世界只有一份,自定义的对象锁是类内部的一个成员变量,每次创建新对象的时候属性是一样的。
线程系列2--Java线程的互斥技术的更多相关文章
- 【java线程系列】java线程系列之java线程池详解
一线程池的概念及为何需要线程池: 我们知道当我们自己创建一个线程时如果该线程执行完任务后就进入死亡状态,这样如果我们需要在次使用一个线程时得重新创建一个线程,但是线程的创建是要付出一定的代价的,如果在 ...
- 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型
关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...
- Java并发编程系列-(7) Java线程安全
7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...
- Java并发编程系列-(6) Java线程池
6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...
- 线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁
当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.E ...
- 【阿里面试系列】Java线程的应用及挑战
文章简介 上一篇文章[「阿里面试系列」搞懂并发编程,轻松应对80%的面试场景]我们了解了进程和线程的发展历史.线程的生命周期.线程的优势和使用场景,这一篇,我们从Java层面更进一步了解线程的使用.关 ...
- java线程系列之三(线程协作)
本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7433673,转载请注明. 上一篇讲述了线程的互斥(同步),但是在很多情况 ...
- 【线程】linux之多线程同步互斥技术
1.同步机制 线程同步机制主要有:互斥量/信号量/条件变量/读写锁等. 2.技术示例 创建2个计数线程A和B,每次计数加1,当为偶数时,A线程计数:当为奇数时,B线程计数. 源码: ...
- 并发编程系列:Java线程池的使用方式,核心运行原理、以及注意事项
并发编程系列: 高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 线程池的缘由 java中为了提高并发度,可以使用多线程共同执行,但是如果有大量线程短时间之内被创建和销毁,会占用大量的 ...
- 面试官系统精讲Java源码及大厂真题系列之Java线程安全的解决办法
1. 背景 1.1 static修饰类变量.方法.方法块. public + static = 该变量任何类都可以直接访问,而且无需初始化类,直接使用 类名.static 变量 1.2 多个线程同时 ...
随机推荐
- 安装多个ORACLE导致多个Oracle HOME的情况!
Oracle由于版本的不同,在注册表中产生的注册表信息也有所不同,但主要的键值信息还是一样的,例如Oracle10g比oracle9i在注册表中表现的更为“简洁”,在未知的情况下,获取Oracle10 ...
- 谷歌浏览器禁用JS步骤
前奏: 当你想访问一个页面,因为不符合访问条件,而被JS阻拦:或者你打开的页面特效太多,干扰视线:亦或者JS的某个功能禁止了你的某些行为: 是不是很难受, 好办,咱给他禁了不就好啦,大胆地屏蔽它,不管 ...
- 斐波那契数列(js)
//斐波那契数列:后一个数等于前面两个数的和 //0,1,1,2,3,5,8,13,21.... let readline = require("readline-sync"); ...
- mysql float 精度丢失
mysql 中保存了字段 float s=0.3 直接执行sql 查出来是 0.3 但是JPA 执行查询结果是 0.2999 换成decimal 就可以
- windows环境下,kafka常用命令
创建topics kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partition 3 - ...
- hadoop-hive的内表和外表
--创建内表create table if not exists employee(id int comment 'empoyeeid',dateincompany string comment 'd ...
- 【死磕 Java 集合】— ConcurrentSkipListMap源码分析
转自:http://cmsblogs.com/?p=4773 [隐藏目录] 前情提要 简介 存储结构 源码分析 主要内部类 构造方法 添加元素 添加元素举例 删除元素 删除元素举例 查找元素 查找元素 ...
- 4、nfs(存储服务器)
1.NFS基本概述 NFS是Network File System的缩写及网络文件系统.NFS的主要功能是通过局域网络让不同的主机系统之间可以共享文件或目录. 通常中小企业首选NFS作为集群架构的存储 ...
- 《设计模式之美》 <01>为什么需要学习掌握设计模式?
1. 应对面试中的设计模式相关问 题学习设计模式和算法一样,最功利.最直接的目的,可能就是应对面试了.不管你是前端工程师.后端工程师,还是全栈工程师,在求职面试中,设计模式问题是被问得频率比较高的一类 ...
- 开源框架相关面试问题-retrofit网络框架面试问题讲解
retrofit使用简介: 在retrofit中通过一个接口作为Http请求的api接口.注意:@GET("url")中的url只是一个路径,不包含主机号的. 创建一个retrof ...