synchronized

使用synchronized实现同步有2种方式:

  • 同步方法(静态与非静态)
  • 同步代码块

任何Java对象均可作为锁使用,其中,使用的锁对象有以下3种:

  • 静态同步方法中,锁是当前类的Class对象
  • 非静态同步方法中,锁是当前对象this(调用该方法的对象)
  • 同步代码块中,琐是手动配置的对象

同步方法

private synchronized void f()
{
//...
}

同步代码块

private void f()
{
synchronized(this)
{
//...
}
}

Lock

Lock接口中规定了锁必须实现的一些方法

  • void lock()
  • void unlock()
  • boolean tryLock()
  • boolean tryLock(long time, TimeUnit unit)
  • Condition newCondition()

Lock接口的实现类有ReentarntLockReentrantReadWriteLock2种,它们都提供了非公平锁和公平锁2种形式。

ReentrantLock

可重入锁,线程可以重复的获取已经持有的锁。

锁中维护着一个持有计数,来追踪对lock方法的嵌套调用,每次lock计数加1,每次unlock计数减1。

只有持有计数为0时,才释放锁。

使用示例

private Lock lock=new ReentrantLock();

private void f()
{
lock.lock();
try
{
// ...
}
finally
{
lock.unlock();
}
}

公平锁,线程调度器将优先(并不保证一定)执行等待时间最长的线程。

在创建ReentrantLock时,可以传入Boolean参数true,创建一个公平锁。

Lock fairLock=new ReentrantLock(true);

除了使用lock()获取锁外,还可以使用tryLock()尝试获取锁,如果成功,返回true,否则,返回false,并且线程可以立即离开去做其它事情。

还可以调用传入超时参数。

ReentrantReadWriteLock

可重入读写锁。如果对一个数据结构进行读操作的次数远远大于写操作的次数,就可以使用读写锁提高性能。

使用示例

private ReentrantReadWriteLock lock=new ReentrantReadWriteLock();// 创建读写锁
private Lock readLock=lock.readLock();// 读锁
private Lock writeLock=lock.writeLock();// 写锁 // 读操作加读锁
public void read()
{
readLock.lock();
try
{
// ...
}
finally
{
readLock.unlock();
}
} // 写操作加写锁
public void write()
{
writeLock.lock();
try
{
// ...
}
finally
{
writeLock.unlock();
}
}

死锁

死锁问题的产生,是由于线程A和线程B互相持有对方需要获取的锁对象导致的

private static final Object lockA=new Object();
private static final Object lockB=new Object(); private void deadLock()
{
Thread t1=new Thread(()->{
synchronized(lockA)
{
sleep(1L);
synchronized(lockB)
{
System.out.println("thread 1");
}
}
}); Thread t2=new Thread(()->{
synchronized(lockB)
{
sleep(1L);
synchronized(lockA)
{
System.out.println("thread 2");
}
}
}); t1.start();
t2.start();
} private void sleep(long timeout)
{
try
{
TimeUnit.SECONDS.sleep(timeout);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}

死锁问题一旦发生,程序就会挂起。所以,必须避免死锁的发生,有以下几个方式

  • 避免在一个线程中同时获取多个锁
  • 尝试使用定时锁(lock.tryLock(timeout)),替代普通锁机制

Java并发编程中的锁的更多相关文章

  1. Java并发编程中的相关注解

    引自:http://www.cnblogs.com/phoebus0501/archive/2011/02/21/1960077.html Java并发编程中,用到了一些专门为并发编程准备的 Anno ...

  2. Java并发编程中的设计模式解析(二)一个单例的七种写法

    Java单例模式是最常见的设计模式之一,广泛应用于各种框架.中间件和应用开发中.单例模式实现起来比较简单,基本是每个Java工程师都能信手拈来的,本文将结合多线程.类的加载等知识,系统地介绍一下单例模 ...

  3. Java并发编程:Concurrent锁机制解析

    Java并发编程:Concurrent锁机制解析 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: # ...

  4. Java并发编程中的若干核心技术,向高手进阶!

    来源:http://www.jianshu.com/p/5f499f8212e7 引言 本文试图从一个更高的视角来总结Java语言中的并发编程内容,希望阅读完本文之后,可以收获一些内容,至少应该知道在 ...

  5. Java并发编程中的设计模式解析(一)

    Java并发编程,除了被用于各种Web应用.分布式系统和大数据系统,构成高并发系统的核心基础外,其本身也蕴含着大量的设计模式思想在里面.这一系列文章主要是结合Java源码,对并发编程中使用到的.实现的 ...

  6. Java并发编程:同步锁、读写锁

    之前我们说过线程安全问题可以用锁机制来解决,即线程必要要先获得锁,之后才能进行其他操作.其实在 Java 的 API 中有这样一些锁类可以提供给我们使用,与其他对象作为锁相比,它们具有更强大的功能. ...

  7. Java并发编程中线程池源码分析及使用

    当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...

  8. Java 并发编程中的 Executor 框架与线程池

    Java 5 开始引入 Conccurent 软件包,提供完备的并发能力,对线程池有了更好的支持.其中,Executor 框架是最值得称道的. Executor框架是指java 5中引入的一系列并发库 ...

  9. Java 并发编程中的 CountDownLatch 锁用于多个线程同时开始运行或主线程等待子线程结束

    Java 5 开始引入的 Concurrent 并发软件包里面的 CountDownLatch 其实可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是 ...

随机推荐

  1. 程序时间计算函数(被tle出阴影来了)

    初次意识到程序的时间复杂度(tle多了 ) 第一次写博客(被大佬们的博客所折服orz) 拿打素数表的程序为例 优化前代码: #include<iostream> #include<c ...

  2. Jmeter 设置中文

    1.正常启动jmeter.bat 2.点击[Options]选项,弹出下拉菜单选择[Choose Language]选项3.选择[Choose Language]选项,弹出下一级菜单选择[Chines ...

  3. 置的测试文件的大小一定要大过你的内存(最佳为内存的两倍大小),不然linux会给你的读写的内容进行缓存,会使数值非常不准确。

    使用iozone测试磁盘性能   IOzone是一个文件系统测试基准工具.可以测试不同的操作系统中文件系统的读写性能.可以通过 write, re-write, read, re-read, rand ...

  4. 使用LUKS加密你的磁盘

    计算机数据的安全,保密性在现在的生活中显得越来越重要.随着数字化的时代的来临,越来越多的数据被数字化,特别是更多有关于我们隐私的数据在不断生成,甚至还有我们需要离线保存的密钥等.而且通常我们使用磁盘, ...

  5. 搭建LAMP环境部署opensns微博网站

    搭建LAMP环境部署opensns微博网站 实验环境 centos7 ip: 192.168.121.17 一.关闭防火墙和selinux [root@localhost ~]# systemctl ...

  6. Linux xargs命令-(转载)

    xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具.它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理.通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从 ...

  7. systemd 进程管理详解

    systemd进程管理 systemd管理的优势 1.最新系统都采用systemd管理(RedHat7,CentOS7,Ubuntu15...) 2.CentOS7 支持开机并行启动服务,显著提高开机 ...

  8. p4 学习笔记

    新版的p4编译器编译p4-14 p4c test.p4 -o meter --std p4-14 #p4-14和p4-16存在较大差异,参考p4代码时需注意 p4语言特性 无符号数bit类型的操作:此 ...

  9. 支持边云协同终身学习特性,KubeEdge子项目Sedna 0.3.0版本发布!

    摘要:随着边缘设备数量指数级增长以及设备性能的提升,边云协同机器学习应运而生,以期打通机器学习的最后一公里. 本文分享自华为云社区<支持边云协同终身学习特性,KubeEdge子项目Sedna 0 ...

  10. 『言善信』Fiddler工具 — 4、Fiddler面布局详解【工具栏】

    目录 (一)工具栏详细介绍 1.第一组工具: 2.第二组工具: 3.第三组工具: 4.第四组工具: (二)工具栏使用说明 1.Fiddler修改代理端口: 2.过滤Tunnel to...443请求链 ...