synchronized方法加锁和ReentrantLock锁
继承Thread类----同步方法,同步代码块
实现Runnable接口----同步方法,同步代码块
练 习: 银行有一个账户。
有两个储户分别向同一个账户存3000元,每次存1000,存3次。每次存完打
印账户余额。
问题:该程序是否有安全问题,如果有,如何解决?
1. synchronized方法加锁 继承Thread类----同步方法
// synchronized方法加锁 继承Thread类----同步方法
class Account {
private double balance = 0;
public Account(double balance) {
this.balance = balance;
}
public synchronized void deposit(double amt){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
balance+=amt;
System.out.println(Thread.currentThread().getName()+"存钱"+amt+"成功,余额为 "+balance);
}
}
class Customer extends Thread{
private Account acct;
public Customer(Account acct) {
this.acct = acct;
}
@Override
public void run() {
for(int i=0;i<3;i++){
acct.deposit(1000);
}
}
}
public class ThreadLockExer1 { // 主类
public static void main(String[] args) {
Account acct = new Account(0);
Customer cust1 = new Customer(acct);
Customer cust2 = new Customer(acct);
cust1.setName("甲");
cust2.setName("乙");
cust1.start();
cust2.start();
}
}
2. synchronized方法加锁 实现Runnable接口类----同步方法
//实现Runnable接口类----同步方法
class Account {
private double balance = 0;
public Account(double balance) {
this.balance = balance;
}
public synchronized void deposit(double amt){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
balance+=amt;
System.out.println(Thread.currentThread().getName()+"存钱"+amt+"成功,余额为 "+balance);
}
}
class Customer implements Runnable{
private Account acct;
public Customer(Account acct) {
this.acct = acct;
}
@Override
public void run() {
for(int i=0;i<3;i++){
acct.deposit(1000);
}
}
}
public class ThreadLockExer2 { // 主类
public static void main(String[] args) {
Account acct = new Account(0);
Customer cust= new Customer(acct);
Thread t1 = new Thread(cust);
Thread t2 = new Thread(cust);
t1.setName("甲");
t2.setName("乙");
t1.start();
t2.start();
}
}
3. synchronized方法加锁 继承Thread类—同步代码块
class Account {
private double balance = 0;
public Account(double balance) {
this.balance = balance;
}
public void deposit(double amt){
synchronized (Customer.class){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
balance+=amt;
System.out.println(Thread.currentThread().getName()+"存钱"+amt+"成功,余额为 "+balance);
}
}
}
class Customer extends Thread{
private Account acct;
public Customer(Account acct) {
this.acct = acct;
}
@Override
public void run() {
for(int i=0;i<3;i++){
acct.deposit(1000);
}
}
}
public class ThreadLockExer3 { // 主类
public static void main(String[] args) {
Account acct = new Account(0);
Customer cust1 = new Customer(acct);
Customer cust2 = new Customer(acct);
cust1.setName("甲");
cust2.setName("乙");
cust1.start();
cust2.start();
}
}
4. synchronized方法加锁 实现Runnable接口—同步代码块
class Account {
private double balance = 0;
public Account(double balance) {
this.balance = balance;
}
public void deposit(double amt){
synchronized(this){ // this可替换为Customer.class
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
balance+=amt;
System.out.println(Thread.currentThread().getName()+"存钱"+amt+"成功,余额为 "+balance);
}
}
}
class Customer implements Runnable{
private Account acct;
public Customer(Account acct) {
this.acct = acct;
}
@Override
public void run() {
for(int i=0;i<3;i++){
acct.deposit(1000);
}
}
}
public class ThreadLockExer4 { // 主类
public static void main(String[] args) {
Account acct = new Account(0);
Customer cust= new Customer(acct);
Thread t1 = new Thread(cust);
Thread t2 = new Thread(cust);
t1.setName("甲");
t2.setName("乙");
t1.start();
t2.start();
}
}
5. Reentrantlock加锁 实现Runnable接口—公平锁
import java.util.concurrent.locks.ReentrantLock; // Reentrantlock加锁 实现Runnable接口---公平锁
class Account {
private double balance = 0;
public Account(double balance) {
this.balance = balance;
}
public void deposit(double amt){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
balance+=amt;
System.out.println(Thread.currentThread().getName()+"存钱"+amt+"成功,余额为 "+balance);
}
}
class Customer implements Runnable{
private Account acct;
private ReentrantLock fairlock = new ReentrantLock(true);
public Customer(Account acct) {
this.acct = acct;
}
@Override
public void run() {
try {
fairlock.lock();
for(int i=0;i<3;i++){
acct.deposit(1000);
}
}finally {
fairlock.unlock();
}
}
}
public class ThreadLockExer5 { // 主类
public static void main(String[] args) {
Account acct = new Account(0);
Customer cust= new Customer(acct);
Thread t1 = new Thread(cust);
Thread t2 = new Thread(cust);
t1.setName("甲");
t2.setName("乙");
t1.start();
t2.start();
}
}
6. Reentrantlock加锁 实现继承Thread类—公平锁
package com.atguigu.exer; // Reentrantlock加锁 实现继承Thread类---公平锁
// 注意: 继承类有多个对象,ReentrantLock必须声明为static
import java.util.concurrent.locks.ReentrantLock;
/**
* @author lk46
* @create 2021-11-03 15:13
*/
class Account {
private double balance = 0;
public Account(double balance) {
this.balance = balance;
}
public synchronized void deposit(double amt){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
balance+=amt;
System.out.println(Thread.currentThread().getName()+"存钱"+amt+"成功,余额为 "+balance);
}
}
class Customer extends Thread{
private Account acct;
private static ReentrantLock fairlock = new ReentrantLock(true); // 继承类有多个对象,ReentrantLock必须声明为static
public Customer(Account acct) {
this.acct = acct;
}
@Override
public void run() {
try {
fairlock.lock();
for(int i=0;i<3;i++){
acct.deposit(1000);
}
}finally{
fairlock.unlock();
}
}
}
public class ThreadLockExer6{ // 主类
public static void main(String[] args) {
Account acct = new Account(0);
Customer cust1 = new Customer(acct);
Customer cust2 = new Customer(acct);
cust1.setName("甲");
cust2.setName("乙");
cust1.start();
cust2.start();
}
}