java并发编程

1.常用类介绍

Semaphore

Semaphore 类是一个计数信号量,必须由获取它的线程释放, 通常用于限制可以访问某些资源(物理或逻辑的)线程数目。

Semaphore包含三种操作

  1. 初始化

  2. 获取acquire()

  3. 释放 release()

当信号量大于0的时候semaphore会响应线程请求,释放资源,当信号量等于0时即阻塞线程。

Semaphore有两种模式,公平模式和非公平模式

公平模式遵循FIFO,按照acquire的顺序来分配资源,非公平则为抢占式的。

Semaphore的类图如下,使用内部类Sync继承AbstractQueuedSynchronizer实现

classDiagram
Serializable <|-- Semaphore : implements
Semaphore *-- Sync
AbstractQueuedSynchronizer <|-- Sync
Sync <|-- NonfairSync
Sync <|-- FairSync

class Semaphore{
Semaphore : -Sync sync
Semaphore: +Semaphore(int permits)
Semaphore: +Semaphore(int permits, boolean fair)
Semaphore: +acquire()
Semaphore: +acquire(int permits)
Semaphore: +release()
Semaphore: +release(int permits)
}

class Sync{
...
}
class NonfairSync{
...
}
class FairSync{
...
}

2.名词解释

2.1 线程安全

如果一个进程中有多个线程在同时运行同一段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

2.2 可重入锁和不可重入锁

可重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。意义之一在于防止死锁*。

实现原理:每个锁关联一个请求计数器和占有他的线程,当计数为0时,锁未被占用,当线程请求占用锁时,jvm标记锁的占有者,且将请求计数器置为1。同一线程再次请求锁,计数器递增。每当占用线程退出同步块,计数器递减,知道计数器为0,锁被释放。

*:此处的防止死锁实例

public class demo {
public synchronized void methodA(){
methodB();
} public synchronized void methodB(){
//todo do something
}
}

当一个线程调用demo类对象的methodA同步方法,如果demo类对象锁未被占有,该线程占有锁,此时调用methodA会触发methodB的调用,此时需要再获取一次锁,只有可重入可以实现。

如下,子类覆写了父类的synchonized方法,然后调用父类中的方法,此时如果没有可重入的锁,那么这段代码将产生死锁

public class Demo {
int i = 10; public synchronized void parent() {
i--;
System.out.println("parent:" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
} static class Demo2 extends Demo {
@Override
public synchronized void parent() {
try {
while (i > 1) {
i--;
System.out.println("child:" + i);
Thread.sleep(100);
super.parent();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Demo2 demo2 = new Demo2();
demo2.parent();
}
});
thread.start();
}
}

synchronized和ReentrantLock都是可重入锁

java并发编程[持续更新]的更多相关文章

  1. java并发编程(更新)

    概念理解:①串行程序②并发程序: 线程安全问题: 同一进程中的所有线程共享进程中的内存地址空间.如果没有明确的同步机制来管理共享数据,那么当一个线程正在使用某个变量时,另一个线程可能同时访问这个变量, ...

  2. 《Java并发编程实战》学习笔记 线程安全、共享对象和组合对象

    Java Concurrency in Practice,一本完美的Java并发参考手册. 查看豆瓣读书 推荐:InfoQ迷你书<Java并发编程的艺术> 第一章 介绍 线程的优势:充分利 ...

  3. Java并发编程75道面试题及答案

    1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...

  4. Java并发编程(1)-Java内存模型

    本文主要是学习Java内存模型的笔记以及加上自己的一些案例分享,如有错误之处请指出. 一 Java内存模型的基础 1.并发编程模型的两个问题 在并发编程中,需要了解并会处理这两个关键问题: 1.1.线 ...

  5. Java并发编程73道面试题及答案 —— 面试稳了

    今天主要整理一下 Java 并发编程在面试中的常见问题,希望对需要的读者有用. 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任 ...

  6. 《java并发编程实战》读书笔记2--对象的共享,可见性,安全发布,线程封闭,不变性

    这章的主要内容是:如何共享和发布对象,从而使它们能够安全地由多个线程同时访问. 内存的可见性 确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化. 上面的程序中NoVisibility可能 ...

  7. JAVA并发编程: CAS和AQS

       版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/u010862794/article/details/72892300 说起JAVA并发编程,就不得不聊 ...

  8. Java并发编程系列-(7) Java线程安全

    7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...

  9. 《Java并发编程的艺术》读书笔记:一、并发编程的目的与挑战

    发现自己有很多读书笔记了,但是一直都是自己闷头背,没有输出,突然想起还有博客圆这么个好平台给我留着位置,可不能荒废了. 此文读的书是<Jvava并发编程的艺术>,方腾飞等著,非常经典的一本 ...

随机推荐

  1. java 中对hashmap进行排序

    public class HashMapSort { public static void main(String[] args) { HashMap<Integer, Student> ...

  2. JAVA集合框架 - Collection

    collection大致介绍 Collection是集合层次结构中的根接口. 集合表示一组对象.有些集合允许重复元素,有些则不允许.有些是有序的,有些是无序的. JDK没有提供此接口的任何直接实现:它 ...

  3. python+opencv切割细胞及细胞团(持续更新)

    内容包括:游离细胞的切割,有效细胞的信息提取,找出非正常细胞,细胞团的切割,找出非正常细胞团 代码较多,请移步到我的github

  4. 如何使用ABP进行软件开发之基础概览

    ABP框架简述 1)简介 在.NET众多的技术框架中,ABP框架(本系列中指aspnetboilerplate项目)以其独特的魅力吸引了一群优秀开发者广泛的使用. 在该框架的赋能之下,开发者可根据需求 ...

  5. Python 图像处理 OpenCV (12): Roberts 算子、 Prewitt 算子、 Sobel 算子和 Laplacian 算子边缘检测技术

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  6. JavaScript基础JavaScript的常用编码惯例(007)

    采用一定的编码惯例,可以使得项目中的代码提到较高的一致性,可读性和可预测性. 1.缩进缩 进可以提高代码的可读性.不过错误的缩进也可能导致代码的误读.有人认为缩进应该使用tab,另外的一些人主张采用4 ...

  7. github Pull Request合入全流程介绍

    图解全流程 详细步骤 1. fork仓库 2. clone fork仓库到本地 3. 关联upstream原仓库 在fork本地仓库输入下面命令进行关联: git remote add upstrea ...

  8. LINUX 下 一些常用的信息显示命令:

    tcsh——shell程序,它可以在登录shell和shell 脚本命令处理器之间做命令语言解释器.stat——显示指定文件的相关信息who.w——显示在线登陆用户whoami——显示用户自己的身份h ...

  9. DBMS_METADATA.GET_DDL查出不存在的列SYS_C00014_20070116:47:09$

    DBMS_METADATA.GET_DDL查出不存在的列SYS_C00014_20070116:47:09$ 前言 很久很久以前,有多久呢? 有多久了,等等我看下截图的日期(溜︿( ̄︶ ̄)︿). 哦, ...

  10. css hack原理及常用hack

    原理:利用不同浏览器对CSS的支持和解析结果不一样编写针对特定浏览器样式.常见的hack有1)属性hack.2)选择器hack.3)IE条件注释 IE条件注释:适用于[IE5, IE9]常见格式如下 ...