今天练习了 Java 的多线程, 提到多线程就基本就会用到锁
Java 通过关键字及几个类实现了锁的机制, 这里先介绍下 Java 都有哪些锁:
一, Java 实现锁的机制:
Java 运行到包含锁的代码时, 获取尝试获取对应的锁, 如果锁被其他线程占用着, 则该线程默认等待, 待这个锁得以释放在去获取, 进而执行锁中的代码.
注: 这里说的尝试获取对应的锁是指当多个线程公用一个锁的时候.
二, 锁的种类
Java 总共就两个锁: 对象锁和类锁
区别:
具体这里分为了对象锁和类锁, 是因为锁作用的范围不同, 如果多个线程采用的是对象锁, 需要要求他们引用同一个对象实例的锁才起作用, 一旦一个线程使用的是不同的对象实例, 就不受这个锁的干预了, 但是类锁不同, 类锁对应的是 class 对象, 这个类的所有实例对应一个 class 对象, 所以他们相当于争抢同一个锁.
对象锁:
说到对象锁, 需要在这了统一一个认识: Java 里的所有代码都是对对象执行的操作
其实每个对象都有一个锁, 只不过对于没有加锁的代码而言, 他们对这个锁视而不见, 因为普通代码的执行根本就不依赖锁.
对象锁的具体表现形式是:
对方法加的锁
代码块加的锁
对方法加的锁长这样:
- 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
- View Code
对代码块加的锁长这样:
- 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
- View Code
实现原理:
具体的实现方式是, 当程序运行到包含锁的代码的时候, 不管是方法还是代码块, 线程会拿到锁域里的所有对象的锁. 如果有方法调用也会递归式的获取.
类锁
类锁一半针对静态代码块或者静态方法. 例子这里就不写了, 就是相当于在上面两个例子前面加个 static 关键字.
只要是调用这个类的方法, 引用类锁的线程争抢的就都是一把锁.
三, 关于锁的关键字:
synchronized
注: 可以指定方法, 可以指定代码块
四, 实现锁的类
- ReentrantLock
- Reentrant?ReadWriteLock
这两种锁和 synchronized 关键字的区别:
? 当锁被其他线程获取, 当前线程可以不必阻塞住.
关键字的方式是由系统自动释放锁, 而下面必须要手动操作.
ReentranLock 的用法
简单的用法如下, 功能同关键字 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
- View Code
? 实现中断线程
- 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
- View Code
? 实现检测锁状态
- @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
- View Code
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
- View Code
来源: http://www.bubuko.com/infodetail-2601581.html