多线程 共享资源 同步锁 java
Java多线程编程:Lock
synchronized是java中的一个关键字,也就是说是Java语言内置的特性。那么为什么会出现Lock呢?
如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁会有三种情况:
1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有;
2)线程执行发生异常,此时JVM会让线程自动释放锁。
3)这个主要是在等待唤醒机制里面的wait()方法,//在等待的时候立即释放锁,方便其他的线程使用锁。而且被唤醒时,就在此处唤醒,
那么如果这个获取锁的线程由于要等待IO或者其他原因(比如调用sleep方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待,试想一下,这多么影响程序执行效率。因此我们需要不论程序的代码块执行的如何最终都将锁对象进行释放,方便其他线程的执行。(此处后面有一个简单的demo起始就是将锁对象人工的释放而且是在finally里面的执行)
虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,同时为了更好地释放锁。
为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock。
另外,通过Lock可以知道线程有没有成功获取到锁。这个是synchronized无法办到的。
总结一下,也就是说Lock提供了比synchronized更多的功能。但是要注意以下几点:
1)Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;
2)synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中
3)在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,
但是ReetrantLock的性能能维持常态;
一、Lock锁的简单使用

1 import java.util.concurrent.locks.Lock;
2 import java.util.concurrent.locks.ReentrantLock;
3
4 public class SellTicket implements Runnable {
5
6 // 定义票
7 private int tickets = 100;
8
9 // 定义锁对象
10 private Lock lock = new ReentrantLock();
11
12 @Override
13 public void run() {
14 while (true) {
15 try {
16 // 加锁
17 lock.lock();
18 if (tickets > 0) {
19 try {
20 Thread.sleep(100);
21 } catch (InterruptedException e) {
22 e.printStackTrace();
23 }
24 System.out.println(Thread.currentThread().getName()
25 + "正在出售第" + (tickets--) + "张票");
26 }
27 } finally {
28 // 释放锁
29 lock.unlock();
30 }
31 }
32 }
33 //注意 这种写法 就是为了防止程序异常 而不放锁 而且还可以清晰的看到那些线程拿到了锁
34 }

出异常的测试 多线程
1 import java.util.concurrent.locks.Lock;
2 import java.util.concurrent.locks.ReentrantLock;
3
4 public class SellTicket implements Runnable {
5
6 // 定义票
7 private int tickets = 100;
8
9 // 定义锁对象
10 private Lock lock = new ReentrantLock();
11
12 @Override
13 public void run() {
14 while (true) {
15 try {
16 // 加锁
17 lock.lock();
18 if (tickets > 0) {
19 try {
20 Thread.sleep(100);
21 } catch (InterruptedException e) {
22 e.printStackTrace();
23 }
24 System.out.println(Thread.currentThread().getName()
25 + "正在出售第" + (tickets--) + "张票");
26 }
int i=1/0;
27 } finally {
28 // 释放锁
29 lock.unlock();
30 }
31 }
32 }
33 //注意 这种写法 就是为了防止程序异常 而不放锁 而且还可以清晰的看到那些线程拿到了锁
34 }
下面是测试类

1 public class RunnableDemo {
2 public static void main(String[] args) {
3 SellTicketsRunnable str = new SellTicketsRunnable();
4
5 Thread tr1 = new Thread(str, "tr1");
6 Thread tr2 = new Thread(str, "tr2");
7 Thread tr3 = new Thread(str, "tr3");
8
9 //
10 tr1.start();
11 tr2.start();
12 tr3.start();
13 }
14 }
多线程 共享资源 同步锁 java的更多相关文章
- 【Java】多线程冲突解决——同步锁
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827547.html 解决并行冲突最有效的方法就是加同步锁,主要有以下几种方法: 1:动态方法 ...
- python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio
摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...
- Java:多线程,使用同步锁(Lock)时利用Condition类实现线程间通信
如果程序不使用synchronized关键字来保证同步,而是直接使用Lock对象来保证同步,则系统中不存在隐式的同步监视器,也就不能用wait().notify().notifyAll()方法进行线程 ...
- Java多线程学习---------超详细总结(java 多线程 同步 数据传递 )
目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么 ...
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- Java多线程简析——Synchronized(同步锁)、Lock以及线程池
Java多线程 Java中,可运行的程序都是有一个或多个进程组成.进程则是由多个线程组成的.最简单的一个进程,会包括mian线程以及GC线程. 线程的状态 线程状态由以下一张网上图片来说明: 在图中, ...
- JAVA学习笔记 -- 多线程之共享资源
在多线程程序执行过程中,可能会涉及到两个或者多个线程试图同一时候訪问同一个资源.为了防止这样的情况的发生,必须在线程使用共享资源时给资源"上锁",以阻挡其他线程的訪问. 而这样的机 ...
- Java多线程系列 基础篇06 synchronized(同步锁)
转载 http://www.cnblogs.com/paddix/ 作者:liuxiaopeng http://www.infoq.com/cn/articles/java-se-16-synchro ...
- java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决
0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...
随机推荐
- 使用字蛛教程以及遇到的bug
前言: 前段时间刚完成一个外项目,歇了几天,老大让我看看公司的官网,优化一下,发现移动端的字体下载特别慢,才发现引用了字体包,一个字体包就达到了11M,想着既然有了图片压缩,那么应该有字体压缩,所以百 ...
- 走近Java之包装器类Integer
前几天,有个同事问了我一个关于Integer类赋值的问题,很有意思,我们一起来看一下(如果有说的不正确的地方,欢迎大家指正). 如上图,同样是赋值,但是两次比较的结果完全不同.我们走近了解一下. 在I ...
- springcloud-路由Zull
1. 场景描述 今天接着介绍springcloud,今天介绍下springcloud的路由网关-Zull,外围系统或者用户通过网关访问服务,网关通过注册中心找到对应提供服务的客户端,网关也需要到注册中 ...
- leetcode的Hot100系列--3. 无重复字符的最长子串--滑动窗口
可以先想下这两个问题: 1.怎样使用滑动窗口? 2.如何快速的解决字符查重问题? 滑动窗口 可以想象一下有两个指针,一个叫begin,一个叫now 这两个指针就指定了当前正在比较无重复的字符串,当再往 ...
- NOIP2002 字串变换题解(双向搜索)
65. [NOIP2002] 字串变换 时间限制:1 s 内存限制:128 MB [问题描述] 已知有两个字串A$, B$及一组字串变换的规则(至多6个规则): A1$ -> B1$ A2$ ...
- 使用DQL查询数据库
DQL ( Data Query Language) 是数据查询语言,如 Select 语句#### 一.DQL 语法 ```sqlSELECT [ALL | DISTINCT]{* | table. ...
- 苹果IOS内购二次验证返回state为21002的坑
项目是三四年前的老项目,之前有IOS内购二次验证的接口,貌似很久都没用了,然而最近IOS的妹子说接口用不了,让我看看啥问题.接口流程时很简单的,就是前端IOS在购买成功之后,接收到receipt后进行 ...
- Excel催化剂开源第13波-VSTO开发之DataGridView控件几个小坑
Excel催化剂内部大量使用了DataGridView,这其中有一些小坑,花了力气才解决的,在此给广大开发者作简单分享. 为何要使用DataGridView而不是其他控件如ListBox.ListVi ...
- js数字格式化(截断格式化或四舍五入格式化)
/*** * 数字格式化(适合金融产品截断小数位后展示) * @param num * @param pattern (标准格式:#,###.## 或#.## 或#,###00.00) * @para ...
- android 界面提示框架WisdomProgressHUD,为金典而生
一:简述 今天给android开发者们,推荐一个金典的界面提示框架WisdomProgressHUD,使用简洁方便. WisdomProgressHUD 是一个半透明的 HUD 指示器. Wisdom ...