今天练习了Java的多线程,提到多线程就基本就会用到锁
Java通过关键字及几个类实现了锁的机制,这里先介绍下Java都有哪些锁:
 
一、Java实现锁的机制:
Java运行到包含锁的代码时,获取尝试获取对应的锁,如果锁被其他线程占用着,则该线程默认等待,待这个锁得以释放在去获取,进而执行锁中的代码。
注:这里说的尝试获取对应的锁是指当多个线程公用一个锁的时候。
 
二、锁的种类
Java总共就两个锁:对象锁和类锁
 
区别:
具体这里分为了对象锁和类锁,是因为锁作用的范围不同,如果多个线程采用的是对象锁,需要要求他们引用同一个对象实例的锁才起作用,一旦一个线程使用的是不同的对象实例,就不受这个锁的干预了,但是类锁不同,类锁对应的是class对象,这个类的所有实例对应一个class对象,所以他们相当于争抢同一个锁。
 
对象锁:
说到对象锁,需要在这了统一一个认识:Java里的所有代码都是对对象执行的操作
其实每个对象都有一个锁,只不过对于没有加锁的代码而言,他们对这个锁视而不见,因为普通代码的执行根本就不依赖锁。
对象锁的具体表现形式是:
  1. 对方法加的锁
  2. 代码块加的锁
 
对方法加的锁长这样:
 public synchronized void output1() {
for(int i=0;i<10;i++) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果如下:
Synchronized test
thread1
thread1
thread1
thread1
thread1
thread1
thread1
thread1
thread1
thread1
thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
 
对代码块加的锁长这样:
 public void output2() {
for(int i=0;i<1;i++) {
System.out.println(Thread.currentThread().getName() + "---read");
}
synchronized(Synchronized_test.syn) {
for(int i=0;i<10;i++) {
System.out.println(Thread.currentThread().getName() + "--- write");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果如下:
Synchronized test
thread1---read
thread2---read
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2—write
 
实现原理:
具体的实现方式是,当程序运行到包含锁的代码的时候,不管是方法还是代码块,线程会拿到锁域里的所有对象的锁。如果有方法调用也会递归式的获取。
 
类锁
类锁一半针对静态代码块或者静态方法。例子这里就不写了,就是相当于在上面两个例子前面加个static关键字。
只要是调用这个类的方法,引用类锁的线程争抢的就都是一把锁。
 
 
三、关于锁的关键字:
synchronized  
注:可以指定方法,可以指定代码块
 
四、实现锁的类
1. ReentrantLock
2. Reentrant​ReadWriteLock
 
这两种锁和synchronized关键字的区别:
  1. ​当锁被其他线程获取,当前线程可以不必阻塞住。
  2. 关键字的方式是由系统自动释放锁,而下面必须要手动操作。
 
ReentranLock的用法
  1. 简单的用法如下,功能同关键字synchronized
 @Override
public void run() {
lock.lock();
for(int i=1;i<10;i++) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.unlock();
}
运行结果如下:
lock test
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1
 
  1. ​实现中断线程
 public class Lock_interrupt_test implements Runnable {
private Lock lock = null;
public Lock_interrupt_test() {
lock = new ReentrantLock();
} @Override
public void run() {
try {
lock.lockInterruptibly();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName());
Thread.sleep(100);
}
} catch (InterruptedException e1) {
e1.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
System.out.println("lock interrupt test");
Lock_interrupt_test lock_interrupt_test = new
Lock_interrupt_test();
Thread thread1 = new Thread(lock_interrupt_test, "thread1");
Thread thread2 = new Thread(lock_interrupt_test, "thread2");
thread1.start();
thread2.start();
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
State state1 = thread1.getState();
Thread thread = state1.toString().equals("TIMED_WAITING")?
thread1:thread2;
System.out.println("interrupt " + thread.getName());
thread.interrupt();
}
}
运行结果如下:
lock interrupt test
thread1
thread1
thread1
thread1
interrupt thread1
java.lang.InterruptedException: sleep interrupted
at java.base/java.lang.Thread.sleep(Native Method)
at lock_type.Lock_interrupt_test.run(Lock_interrupt_test.java:21)
at java.base/java.lang.Thread.run(Thread.java:844)
thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
 
  1. ​实现检测锁状态
 @Override
public void run() {
try {
if (lock.tryLock(400,TimeUnit.MILLISECONDS)) {
System.out.println(Thread.currentThread().getName() + " have get the lock");
for (int i = 1; i < 10; i++) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " have
return the lock");
lock.unlock();
}
else {
for (int i = 1; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " locking");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
运行结果如下:
lock try test
Thread-0 have get the lock
Thread-0
Thread-0
Thread-0
Thread-0
Thread-1 locking
Thread-0
Thread-1 locking
Thread-0
Thread-1 locking
Thread-0
Thread-1 locking
Thread-0
Thread-1 locking
Thread-0
Thread-1 locking
Thread-0 have return the lock
Thread-1 locking
Thread-1 locking
Thread-1 locking
 
ReentrantReadWriteLock的用法
实现读写分离锁
 @Override
public void run() {
lock.readLock().lock();
for(int i=0;i<10;i++) {
System.out.println(Thread.currentThread().getName() + "---read");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.readLock().unlock();
lock.writeLock().lock();
for(int i=0;i<10;i++) {
System.out.println(Thread.currentThread().getName() + "---write");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.writeLock().unlock();
}
运行结果如下:
lock read write test
thread2---read
thread1---read
thread1---read
thread2---read
thread1---read
thread2---read
thread2---read
thread1---read
thread1---read
thread2---read
thread1---read
thread2---read
thread1---read
thread2---read
thread1---read
thread2---read
thread2---read
thread1---read
thread2---read
thread1---read
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread1---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write
thread2---write

Java的锁的更多相关文章

  1. java的锁机制

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在Java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...

  2. JAVA线程锁-读写锁

    JAVA线程锁,除Lock的传统锁,又有两种特殊锁,叫读写锁ReadWriteLock 其中多个读锁不互斥,读锁和写锁互斥,写锁和写锁互斥 例子: /** * java线程锁分为读写锁 ReadWri ...

  3. Java线程锁一个简单Lock

    /** * @author * * Lock 是java.util.concurrent.locks下提供的java线程锁,作用跟synchronized类似, * 单是比它更加面向对象,两个线程执行 ...

  4. paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)

    paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象) 1     锁的缺点 2     CAS(Compare ...

  5. Java偏向锁实现原理(Biased Locking)

    http://kenwublog.com/theory-of-java-biased-locking 阅读本文的读者,需要对Java轻量级锁有一定的了解,知道lock record, mark wor ...

  6. Java分布式锁之数据库实现

    之前的文章<Java分布式锁实现>中列举了分布式锁的3种实现方式,分别是基于数据库实现,基于缓存实现和基于zookeeper实现.三种实现方式各有可取之处,本篇文章就详细讲解一下Java分 ...

  7. Java类锁和对象锁

    一.类锁和对象锁 二.使用注意 三.参考资料 一.类锁和对象锁 类锁:在代码中的方法上加了static和synchronized的锁,或者synchronized(xxx.class) 对象锁:在代码 ...

  8. java的锁机制——synchronized

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...

  9. Java多线程--锁的优化

    Java多线程--锁的优化 提高锁的性能 减少锁的持有时间 一个线程如果持有锁太长时间,其他线程就必须等待相应的时间,如果有多个线程都在等待该资源,整体性能必然下降.所有有必要减少单个线程持有锁的时间 ...

随机推荐

  1. 利用JQuery直接调用asp.net后台方法

    利用JQuery的$.ajax()可以很方便的调用asp.net的后台方法. [WebMethod]   命名空间 1.无参数的方法调用, 注意:1.方法一定要静态方法,而且要有[WebMethod] ...

  2. 速度之王 — LZ4压缩算法(二)

    LZ4 (Extremely Fast Compression algorithm) 项目:http://code.google.com/p/lz4/ 作者:Yann Collet 本文作者:zhan ...

  3. Slop One 算法

    Slope One 算法是由 Daniel Lemire 教授在 2005 年提出的一个 Item-Based 推荐算法. Slope One 算法试图同时满足这样的的 5 个目标: 易于实现和维护: ...

  4. Windows2008修改密码策略简单介绍

    Windows2008修改密码策略简单介绍 Windows的密码策略,确实是挺繁琐的,刚接触SharePoint2010,装的windows2008 R2,就遇到了改密码策略的问题. 打开本地安全策略 ...

  5. obj-c编程17:键值观察(KVO)

    说完了前面一篇KVC,不能不说说它的应用KVO(Key-Value Observing)喽.KVO类似于ruby里的hook功能,就是当一个对象属性发生变化时,观察者可以跟踪变化,进而观察或是修正这个 ...

  6. 恶补web之六:javascript知识(1)

    javascript(下称js)是一种轻量级编程语言,它可以插入html页面然后由浏览器执行. document.write("<h1>...</h1>") ...

  7. Word Break(动态规划)

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...

  8. AS3编程规范

    整理了一些AS3的编程规范,有些规则对于大部分语言都是适用的,有什么问题请提出来,我会持续改进这份规范,谢谢!   [参考资料] 1.http://opensource.adobe.com/wiki/ ...

  9. 发现DELL笔记本一个很弱智的问题

    以前用联想的笔记本,最近联想笔记本坏了,用的是公司的DELL笔记本,发现DELL笔记本一个很弱智的问题. 关于禁用触摸板的问题. 起因: 由于要经常写程序,我配置的有有线鼠标,但是打字时经常碰到触摸板 ...

  10. R实战 第七篇:网格(grid)

    grid包是R底层的图形系统,可以绘制几乎所有的图形.除了绘制图形之外,grid包还能对图形进行布局.在绘图时,有时候会遇到这样一种情景,客户想把多个代表不同KPI的图形分布到同一个画布(Page)上 ...