赞
踩
锁是一种同步机制,用于控制对共享资源的访问。锁的作用是确保同一时间只有一个线程可以访问共享资源,也就是说保证了线程安全。因此在并发编程中,锁是相当重要的。
(1)多任务环境中才需要;
(2)任务都需要对同一共享资源进行写操作;
(3)对资源的访问是互斥的;
(1)syncronized是jvm层面的内置关键字,lock是java的一个接口;
(2)syncronized实现线程同步时,若线程一阻塞,线程二则一直等待,lock则不会,会自动结束线程;
(3)syncronized会自动释放锁,lock需要手动在finally里释放(unlock),syncronized无法判断是否获得锁的状态,lock可以;
(4)syncronized的锁可重入、不可中断、非公平,lock的锁可重入、可中断、公平;
(5)lock适合大量同步代码的同步问题,syncronized适合少量;
(1)sychronized:非公平、悲观、独享、互斥、可重入的重量级锁
(2)ReentrantLock:默认非公平但可实现公平的、悲观、独享、互斥、可重入、重量级锁
(3)ReentrantReadWriteLock:默认非公平但是可实现公平的、悲观、写独享、读共享、读写、可重入、重量级锁
jvm锁解决不了分布式环境多任务对共享资源竞争的协同操作问题。
(1)不用锁的情况,会出现重卖问题,应避免重卖还有超卖问题
- public class Main {
- public static void main(String[] args) {
- DiyThread diyThread = new DiyThread();
- Thread t1 = new Thread(diyThread,"窗口A");
- Thread t2 = new Thread(diyThread,"窗口B");
- Thread t3 = new Thread(diyThread,"窗口C");
- Thread t4 = new Thread(diyThread,"窗口D");
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
-
- class DiyThread implements Runnable {
- // 成员变量(实例变量):随着对象的创建而存在,随着对象的回收而释放,存储在堆内存的对象中
- private int count = 100;
-
- // 静态变量(类变量):随着类的加载而存在,随着类的消失而消失,存储在方法区(共享数据区)的静态区
- // private static int count = 100;
-
- public void run() {
- while (true) {
- if (count > 0) {
- // 不用锁的情况,会出现重卖问题
- System.out.println(Thread.currentThread().getName() + " -> 售出第" + count + "张火车票");
- count--;
- try {
- // 睡眠50毫秒
- Thread.sleep(50);
- } catch (Exception e) {
- System.out.println(Thread.currentThread().getName() + " : 出现异常 -> " + e.getMessage());
- }
- } else {
- System.out.println(Thread.currentThread().getName() + " : 票已售完");
- break;
- }
- }
- }
- }
(2)使用【同步代码块】使线程串行同步,不然会出现线程不安全的问题
- public class Main {
- public static void main(String[] args) {
- DiyThread diyThread = new DiyThread();
- Thread t1 = new Thread(diyThread,"窗口A");
- Thread t2 = new Thread(diyThread,"窗口B");
- Thread t3 = new Thread(diyThread,"窗口C");
- Thread t4 = new Thread(diyThread,"窗口D");
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
-
- class DiyThread implements Runnable {
- // 成员变量(实例变量):随着对象的创建而存在,随着对象的回收而释放,存储在堆内存的对象中
- private int count = 100;
-
- // 静态变量(类变量):随着类的加载而存在,随着类的消失而消失,存储在方法区(共享数据区)的静态区
- // private static int count = 100;
-
- public void run() {
- while (true) {
- synchronized(this) {
- if (count > 0) {
- System.out.println(Thread.currentThread().getName() + " -> 售出第" + count + "张火车票");
- count--;
- try {
- // 睡眠50毫秒
- Thread.sleep(50);
- } catch (Exception e) {
- System.out.println(Thread.currentThread().getName() + " : 出现异常 -> " + e.getMessage());
- }
- } else {
- System.out.println(Thread.currentThread().getName() + " : 票已售完");
- break;
- }
- }
- }
- }
- }
(3)使用【synchronized】同步函数使线程串行同步,不然会出现线程不安全的问题
- public class Main {
- public static void main(String[] args) {
- DiyThread diyThread = new DiyThread();
- Thread t1 = new Thread(diyThread,"窗口A");
- Thread t2 = new Thread(diyThread,"窗口B");
- Thread t3 = new Thread(diyThread,"窗口C");
- Thread t4 = new Thread(diyThread,"窗口D");
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
-
- class DiyThread implements Runnable {
- // 成员变量(实例变量):随着对象的创建而存在,随着对象的回收而释放,存储在堆内存的对象中
- private int count = 100;
-
- // 静态变量(类变量):随着类的加载而存在,随着类的消失而消失,存储在方法区(共享数据区)的静态区
- // private static int count = 100;
-
- public void run() {
- sale();
- }
-
- private synchronized void sale() {
- while (true) {
- if (count > 0) {
- System.out.println(Thread.currentThread().getName() + " -> 售出第" + count + "张火车票");
- count--;
- try {
- // 睡眠50毫秒
- Thread.sleep(50);
- } catch (Exception e) {
- System.out.println(Thread.currentThread().getName() + " : 出现异常 -> " + e.getMessage());
- }
- } else {
- System.out.println(Thread.currentThread().getName() + " : 票已售完");
- break;
- }
- }
- }
- }
(4)使用【java.util.concurrent】简称juc包的lock锁
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
-
- public class Main {
- public static void main(String[] args) {
- DiyThread diyThread = new DiyThread();
- Thread t1 = new Thread(diyThread,"窗口A");
- Thread t2 = new Thread(diyThread,"窗口B");
- Thread t3 = new Thread(diyThread,"窗口C");
- Thread t4 = new Thread(diyThread,"窗口D");
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
-
- class DiyThread implements Runnable {
- // 成员变量(实例变量):随着对象的创建而存在,随着对象的回收而释放,存储在堆内存的对象中
- private int count = 100;
-
- // 静态变量(类变量):随着类的加载而存在,随着类的消失而消失,存储在方法区(共享数据区)的静态区
- // private static int count = 100;
-
- private Lock lock = new ReentrantLock();
-
- public void run() {
- while (true) {
- lock.lock(); // 加锁之后,以下的业务代码就是单线程环境运行,如4个线程竞争这把锁
- try {
- if (count > 0) {
- System.out.println(Thread.currentThread().getName() + " -> 售出第" + count + "张火车票");
- count--;
- Thread.sleep(50);
- } else {
- System.out.println(Thread.currentThread().getName() + " : 票已售完");
- break;
- }
- } catch (Exception e) {
- System.out.println(Thread.currentThread().getName() + " : 出现异常 -> " + e.getMessage());
- } finally {
- lock.unlock(); // 解锁,最重要原因为避免死锁,无论正确、异常执行,都执行解锁
- }
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。