java多线程:5.1 锁-基础

版权声明:转载请标明来源 https://blog.csdn.net/u010652576/article/details/78395367

什么是锁

提到多线程,立马就有人说加锁,什么是锁,为什么加锁?
锁:从字面意义,什么东西加了锁,那么就只有有钥匙的人才能使用,多线程中的锁,也是这个意思。
为什么加锁:当单线程的时候,无论访问什么资源,都不需要考虑锁的问题,但是当多个线程访问同一个资源,就会发生很多千奇百怪的事,为了保证资源访问时的唯一性,需要对访问资源的线程进行限制,这就是锁的由来。

示例:

public class MultiThread {
    public static void main(String[] args) {
        final String name = "xiaoming";
        new Thread(new Runnable() {
            @Override
            public void run() {
                String[] arr = name.split("");
                while(true){
                    for(int i = 0; i< arr.length;i++){
                        System.out.print(arr[i]);
                    }
                    System.out.println();
                }
            }
        },"小明").start();
        while(true){
            System.out.println("this is "+Thread.currentThread().getName());
        }

    }
}

----输出:
this is main
ng
xiaoming
xiaomingthis is main
this is main
this is main
this is main
this is main

xiaothis is main

通过上述输出内容,发现xiaoming的名字并不能完整的输出,再输出main方法,是因为存在两个线程争夺System.out导致的:线程A获取System.out一顿操作,但是还没有输出,这是cpu切换线程,那么线程B也获取了System.out,然后输出了,这样就把部分线程A写入的数据输出了。这就是多个线程争夺同一个资源,发生了奇怪的事情。

为什么加锁

多线程访问同一个资源为什么会产生各种未可知的问题?这是因为操作的原子性?就是本次操作无法一次性完成,例如:当前线程获取System.out后,无法保证内容的输出一次性完成,当其他线程获取后,输出的内容只有鬼知道。因此多线程访问公共资源,一定要保证操作的原子性,即:本次操作必须一次完成。
为了保证操作的原子性:有两种方法,1 加锁,只要我获得了锁,必须等我完成操作后,其他线程才能访问/修改,即排他性。2 jdk提供一种Atomic包,对基本数据类型和引用,进行包装,保证操作的原子性。atomic的原理就是依赖一种cas机制,当你要更新某一个对象,需要提供该对象的原值,只要当前对象的值与原值相同时,才会进行新值更新,此处只介绍一下原理,具体的可以搜索java Atomic了解底层原理和CAS的ABA问题及解决方案。

锁加在什么地方

访问限制加在什么地方?如果加在资源本身的话,对资源来说也是一种冗余,而且使代码更加耦合,因此我们需要把访问限制独立出来,单独使用一个对象进行访问限制,这就是为什么加锁需要有一个对象。

锁的种类

  1. 自旋锁:让没有获取到锁的线程,一直循环直到获取锁,相当于获取时间片的线程,如果没有获取到时间片,就while循环空判断,要么消耗掉时间片,要么获取锁,自旋锁有:无序自旋锁、有序自旋锁(CHL锁、ticket锁、MCS锁)
  2. 通过方法或代码块加synchronized,早期的StringBuffer、HashTable。
  3. jdk1.5之后,提供了concurrent包,里面提供了lock类,因此就有了:读锁(ReadLock)、写锁(WriteLock)、读写锁(ReadWriteLock)、可重入锁(ReentrantLock)。
    根据不同种类的锁,进行相关的代码解析。

总结

只要涉及到多线程访问同一资源,就需要考虑锁的问题。

猜你喜欢

转载自blog.csdn.net/u010652576/article/details/78395367