线程同步:
同一进程的多个线程共享同一块存储空间
解决冲突:
访问时,加入Synchronized与lock 锁机制,当一个线程获得排他锁,其他线程就必须等待释放
存在问题:
1,一个线程持有锁,会导致其他线程挂起
2,性能问题:加锁,释放锁,会导致较多上下文切换和调度延时
3,优先级倒挂:较高优先级的等待较低优先级的锁
4,sleep不会释放锁
synchronized代码——银行账号案例
package com.chenxb.myThread;
import java.math.BigDecimal;
public class ThreadSynchronized {
public static void main(String[] args) {
//初始化账号金额
Account account = new Account("100000000000000", new BigDecimal("10000"));
//取钱1
GetMoney getMoney = new GetMoney(account, new BigDecimal("5000"));
new Thread(getMoney).start();
//取钱2
GetMoney getMoney2 = new GetMoney(account, new BigDecimal("1000"));
new Thread(getMoney2).start();
//取钱3
GetMoney getMoney3 = new GetMoney(account, new BigDecimal("8000"));
new Thread(getMoney3).start();
}
}
//银行账号
class Account {
String name;
BigDecimal money;
public Account(String name, BigDecimal money) {
this.name = name;
this.money = money;
}
}
//取钱
class GetMoney implements Runnable {
Account account;
BigDecimal getMoney;
public GetMoney(Account account, BigDecimal getMoney) {
this.account = account;
this.getMoney = getMoney;
}
@Override
public void run() {
//synchronized要锁块,锁的对象就是变化的量(需要增删改的对象)
synchronized (account) {
// -1,表示account.money小于getMoney;
if (account.money.compareTo(getMoney) == -1) {
System.out.println("账号金额不够");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money = account.money.subtract(getMoney);
System.out.println(account.money);
}
}
}
Lock代码——银行账号案例
package com.chenxb.myThread;
import java.math.BigDecimal;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadLock {
public static void main(String[] args) {
//注意锁的位置,如果放run()里面,下面new对象时会被覆盖
final ReentrantLock lock = new ReentrantLock();
//初始化账号金额
MyAccount myAccount = new MyAccount("100000000000000", new BigDecimal("10000"));
//取钱1
GetMyMoney getMyMoney = new GetMyMoney(myAccount, new BigDecimal("5000"), lock);
new Thread(getMyMoney).start();
//取钱2
GetMyMoney getMyMoney2 = new GetMyMoney(myAccount, new BigDecimal("1000"), lock);
new Thread(getMyMoney2).start();
//取钱3
GetMyMoney getMyMoney3 = new GetMyMoney(myAccount, new BigDecimal("8000"), lock);
new Thread(getMyMoney3).start();
}
}
//银行账号
class MyAccount {
String name;
BigDecimal money;
public MyAccount(String name, BigDecimal money) {
this.name = name;
this.money = money;
}
}
//取钱
class GetMyMoney implements Runnable {
MyAccount myAccount;
BigDecimal getMoney;
ReentrantLock lock;//定义Lock锁
public GetMyMoney(MyAccount myAccount, BigDecimal getMoney, ReentrantLock lock) {
this.myAccount = myAccount;
this.getMoney = getMoney;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
try {
// -1,表示account.money小于getMoney;
if (myAccount.money.compareTo(getMoney) == -1) {
System.out.println("账号金额不够");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myAccount.money = myAccount.money.subtract(getMoney);
System.out.println(myAccount.money);
} finally {
lock.unlock();
}
}
}