# Java高级之线程同步 **Repository Path**: fpfgitmy_admin/java-high-concurrent ## Basic Information - **Project Name**: Java高级之线程同步 - **Description**: 线程同步 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-04-28 - **Last Updated**: 2021-04-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #### 线程的同步 + 从jdk5.0开始,Java提供了更强大的线程同步机制--通过显示定义同步锁对象来实现同步。铜鼓八所使用Lock对象充当。 + java.util.concurrent.locks.Lock接口时控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占式访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。 + ReentrantLock类实现了Lock锁,它拥有与synchronized相同的并发性和内存语义,在实现线程安全的控制中,比较常用的时ReentrantLock,可以显示加锁、释放锁. ##### 使用lock实现抢票的线程同步 ``` package com.felixfei.study.lock; import java.util.concurrent.locks.ReentrantLock; /** * @author felixfei * @version 1.0 * @date 2021/3/18 20:50 * @describle 使用lock锁实现抢票线程同步 *
* 1. synchronized和Lock的异同? * 相同:二者都可以解决线程安全问题 * 不同:synchronized机制在执行完相应的同步代码以后,自动释放同步监视器。Lock需要手动的启动同步lock(),也需要手动的实现释放锁unlock(); * 优先使用顺序:lock(灵活)->同步代码快->同步方法 */ public class LockTest { public static void main(String[] args) { Window window = new Window(); Thread t1 = new Thread(window); Thread t2 = new Thread(window); Thread t3 = new Thread(window); t1.setName("线程1"); t2.setName("线程2"); t3.setName("线程3"); t1.start(); t2.start(); t3.start(); } } class Window implements Runnable { private static int ticket = 100; // 1.实例化ReentrantLock private ReentrantLock lock = new ReentrantLock(); @Override public void run() { while (true) { try { // 2.调用锁定方法lock(); lock.lock(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < ticket; i++) { System.out.println(Thread.currentThread().getName() + "抢到了票" + ticket); ticket--; } } finally { // 3.调用解锁方法unlock(); lock.unlock(); } } } } ``` ##### 银行存钱的测试题 ``` package com.felixfei.study.lock; import java.util.concurrent.locks.ReentrantLock; /** * @author felixfei * @version 1.0 * @date 2021/3/18 22:19 * @describle 两个人在一个账户存钱,存3000,每次存1000,分别存3次,会不会出现线程安全问题 */ public class Account { public double balance = 0; // 方式3:使用Lock锁 public ReentrantLock lock = new ReentrantLock(); // 方式1:使用同步方法 // public synchronized void save(double balance) { public void save(double balance) { // 方式2:使用同步代码块 //synchronized (Account.class) { try { lock.lock(); this.balance += balance; System.out.println(Thread.currentThread().getName() + "存钱完成,余额为" + this.balance); } finally { lock.unlock(); } //} } public static void main(String[] args) { Account account = new Account(); Person p1 = new Person(account); Person p2 = new Person(account); p1.setName("甲"); p2.setName("乙"); p1.start(); p2.start(); } } class Person extends Thread { private Account acc; public Person(Account acc) { this.acc = acc; } @Override public void run() { for (int i = 0; i < 3; i++) { this.acc.save(1000); } } } ```