今天练习了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. ITU-T Technical Paper: IP网络测量模型

    本文翻译自ITU-T的Technical Paper:<How to increase QoS/QoE of IP-based platform(s) to regionally agreed ...

  2. linux服务搭建----ftp与ftp yum源搭建

    ftp服务     如果没有ftp         yum -y install  vsftpd (前提是你在有yum源的情况下才可以使用这条命令)     service vsftpd  resta ...

  3. 服务器:SATA、PATA及IDE的比较

    SATA SATA全称是Serial Advanced Technology Attachment(串行高级技术附件,一种基于行业标准的串行硬件驱动器接口),是由Intel.IBM.Dell.APT. ...

  4. DB Query Analyzer 5.03 is distributed, EXCEL table name will be enclosed in square bracket

      DB Query Analyzer 5.03 is distributed, table name will be enclosed in square bracket automatically ...

  5. 知物由学|游戏开发者如何从容应对Unity手游风险?

    本文由  网易云发布. "知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不 ...

  6. 使用 focus() 和 blur()

    <html> <head> <style type="text/css"> a:active {color:green} </style& ...

  7. Nuget发布教程

    nuget setApiKey Your-API-Key -Source https://www.nuget.org/api/v2/package nuget spec nuget pack Monk ...

  8. Reportng配置报告地址

    ant build <target name="transform"> <xslt in="./target/surefire-reports/test ...

  9. go 实现struct转map

    从python转golang大约一个月了,对struct的使用还算顺手,但是很多时候还是会想念python的便捷.比如同时遍历两个字典,python使用for (x, y) in zip(map1, ...

  10. Viavdo&ISE&Quartus II级联Modelsim级联仿真

    博主一直致力寻找高效的工作方式,所以一直喜欢折腾软件,从刚开始只用软件IDE自带的编辑器,到Notepad++,再到后来的Vim,从用ISE14.7自带的Isim仿真,到发现更好的Modelsim,再 ...