控制台程序。

除了同步类对象的方法之外,还可以把程序中的语句或代码块制定为synchronized,这种方式更强大,因为可以指定哪个对象从语句或代码块的同步中获益,而不像同步方法那样仅仅是包含代码的对象能获益。这里可以对给定代码块的任何对象设置锁。当对给定对象执行同步的代码块时,就不能执行对相同对象同步的其他代码或方法。

 // Defines a customer account
public class Account {
// Constructor
public Account(int accountNumber, int balance) {
this.accountNumber = accountNumber; // Set the account number
this.balance = balance; // Set the initial balance
} // Return the current balance
public int getBalance() {
return balance;
} // Set the current balance
public void setBalance(int balance) {
this.balance = balance;
} public int getAccountNumber() {
return accountNumber;
} @Override
public String toString() {
return "A/C No. " + accountNumber + " : $" + balance;
} private int balance; // The current account balance
private int accountNumber; // Identifies this account
}
 // Bank account transaction types
public enum TransactionType {DEBIT, CREDIT }
 public class Transaction {
// Constructor
public Transaction(Account account, TransactionType type, int amount) {
this.account = account;
this.type = type;
this.amount = amount;
} public Account getAccount() {
return account;
} public TransactionType getTransactionType() {
return type;
} public int getAmount() {
return amount;
}
@Override
public String toString() {
return type + " A//C: " + account + ": $" + amount;
} private Account account;
private int amount;
private TransactionType type;
}
 // Define the bank

 public class Bank {
// Perform a transaction
public void doTransaction(Transaction transaction) {
switch(transaction.getTransactionType()) {
case CREDIT:
synchronized(transaction.getAccount()) {
System.out.println("Start credit of " +
transaction.getAccount() + " amount: " +
transaction.getAmount()); // Get current balance
int balance = transaction.getAccount().getBalance(); // Credits require a lot of checks...
try {
Thread.sleep(100); } catch(InterruptedException e) {
System.out.println(e);
}
balance += transaction.getAmount(); // Increment the balance
transaction.getAccount().setBalance(balance); // Restore account balance
System.out.println(" End credit of " +
transaction.getAccount() + " amount: " +
transaction.getAmount());
break;
}
case DEBIT:
synchronized(transaction.getAccount()) {
System.out.println("Start debit of " +
transaction.getAccount() + " amount: " +
transaction.getAmount()); // Get current balance
int balance = transaction.getAccount().getBalance(); // Debits require even more checks...
try {
Thread.sleep(150); } catch(InterruptedException e) {
System.out.println(e);
}
balance -= transaction.getAmount(); // Decrement the balance...
transaction.getAccount().setBalance(balance); // Restore account balance System.out.println(" End debit of " +
transaction.getAccount() + " amount: " +
transaction.getAmount());
break;
} default: // We should never get here
System.out.println("Invalid transaction");
System.exit(1);
}
}
}
 public class Clerk implements Runnable {
// Constructor
public Clerk(Bank theBank) {
this.theBank = theBank; // Who the clerk works for
inTray = null; // No transaction initially
} // Receive a transaction
public void doTransaction(Transaction transaction) {
inTray = transaction;
} // The working clerk...
public void run() {
while(true) { // Non-stop work...
while(inTray == null) { // No transaction waiting?
try {
Thread.sleep(150); // Then take a break... } catch(InterruptedException e) {
System.out.println(e);
}
} theBank.doTransaction(inTray);
inTray = null; // In-tray is empty
}
} // Busy check
public boolean isBusy() {
return inTray != null; // A full in-tray means busy!
} private Bank theBank; // The employer - an electronic marvel
private Transaction inTray; // The in-tray holding a transaction
}
 import java.util.Random;

 public class BankOperation4 {
public static void main(String[] args) {
int[] initialBalance = {500, 800}; // The initial account balances
int[] totalCredits = new int[initialBalance.length]; // Two different cr totals
int[] totalDebits = new int[initialBalance.length]; // Two different db totals
int transactionCount = 20; // Number of debits and of credits // Create the account, the bank, and the clerks...
Bank theBank = new Bank(); // Create a bank
Clerk clerk1 = new Clerk(theBank); // Create the first clerk
Clerk clerk2 = new Clerk(theBank); // Create the second clerk // Create the accounts, and initialize total credits and debits
Account[] accounts = new Account[initialBalance.length];
for(int i = 0 ; i < initialBalance.length ; ++i) {
accounts[i] = new Account(i+1, initialBalance[i]); // Create accounts
totalCredits[i] = totalDebits[i] = 0;
}
// Create the threads for the clerks as daemon, and start them off
Thread clerk1Thread = new Thread(clerk1);
Thread clerk2Thread = new Thread(clerk2);
clerk1Thread.setDaemon(true); // Set first as daemon
clerk2Thread.setDaemon(true); // Set second as daemon
clerk1Thread.start(); // Start the first
clerk2Thread.start(); // Start the second // Create transactions randomly distributed between the accounts
Random rand = new Random();
Transaction transaction; // Stores a transaction
int amount = 0; // Stores an amount of money
int select = 0; // Selects an account
for(int i = 1; i <= transactionCount; i++) {
// Choose an account at random for credit operation
select = rand.nextInt(accounts.length);
amount = 50 + rand.nextInt(26); // Generate amount of $50 to $75
transaction = new Transaction(accounts[select], // Account
TransactionType.CREDIT, // Credit transaction
amount); // of amount
totalCredits[select] += amount; // Keep total credit tally // Wait until the first clerk is free
while(clerk1.isBusy()) {
try {
Thread.sleep(25); // Busy so try later
} catch(InterruptedException e) {
System.out.println(e);
}
}
clerk1.doTransaction(transaction); // Now do the credit // choose an account at random for debit operation
select = rand.nextInt(accounts.length);
amount = 30 + rand.nextInt(31); // Generate amount of $30 to $60
transaction = new Transaction(accounts[select], // Account
TransactionType.DEBIT, // Debit transaction
amount); // of amount
totalDebits[select] += amount; // Keep total debit tally // Wait until the second clerk is free
while(clerk2.isBusy()) {
try {
Thread.sleep(25); // Busy so try later
} catch(InterruptedException e) {
System.out.println(e);
}
}
clerk2.doTransaction(transaction); // Now do the debit
} // Wait until both clerks are done
while(clerk1.isBusy() || clerk2.isBusy()) {
try {
Thread.sleep(25); } catch(InterruptedException e) {
System.out.println(e);
}
} // Now output the results
for(int i = 0; i < accounts.length; ++i) {
System.out.println("Account Number:"+accounts[i].getAccountNumber()+"\n"+
"Original balance : $" + initialBalance[i] + "\n" +
"Total credits : $" + totalCredits[i] + "\n" +
"Total debits : $" + totalDebits[i] + "\n" +
"Final balance : $" + accounts[i].getBalance() + "\n" +
"Should be : $" + (initialBalance[i]
+ totalCredits[i]
- totalDebits[i]) + "\n");
}
}
}

synchronized关键字后面圆括号中的表达式用来指定要同步的对象。一旦执行到给定账户对象的同步代码块,就不能再执行为这个账户对象同步的其他代码块或方法。例如,如果用事务的getAccount()方法返回的account[1]对象来引用进行贷款处理的代码块,就不能再执行这个对象的借款处理代码块,但可以执行其他对象的借款处理代码块。

Java基础之线程——管理线程同步代码块(BankOperation4)的更多相关文章

  1. “全栈2019”Java多线程第二十一章:同步代码块产生死锁的例子

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  2. “全栈2019”Java多线程第十八章:同步代码块双重判断详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. Java 基础 线程的Runnable接口 /线程的同步方法 /同步代码块

    笔记: /**通过 Runnable接口来实现多线程 * 1. 创建一个实现runnable 接口的类 * 2. 在类中实现接口的run() 抽象方法 * 3. 创建一个runnable 接口实现类的 ...

  4. 线程执行synchronized同步代码块时再次重入该锁过程中抛异常,是否会释放锁

    一个线程执行synchronized同步代码时,再次重入该锁过程中,如果抛出异常,会释放锁吗? 如果锁的计数器为1,抛出异常,会直接释放锁: 那如果锁的计数器为2,抛出异常,会直接释放锁吗? 来简单测 ...

  5. Android(java)学习笔记68:同步代码块 和 同步方法 的应用

    1. 同步代码块 和 同步方法 代码示例: (1)目标类,如下: package cn.himi.text; public class SellTicket implements Runnable { ...

  6. Android(java)学习笔记8:同步代码块 和 同步方法 的应用

    1. 同步代码块 和 同步方法 代码示例: (1)目标类,如下: package cn.himi.text; public class SellTicket implements Runnable { ...

  7. 【JAVA基础&Python】静态/非静态代码块

    /* * * static静态代码块: * 调用静态属性的时候 对应类里面的静态代码块就会被直接执行 * 注意: 只会执行一次,只能调用类内静态结构的(方法/属性) * 作用: 初始化类的属性 * * ...

  8. JAVA基础知识之多线程——线程同步

    线程安全问题 多个线程同时访问同一资源的时候有可能会出现信息不一致的情况,这是线程安全问题,下面是一个例子, Account.class , 定义一个Account模型 package threads ...

  9. 彻底理解线程同步与同步代码块synchronized

    public class Demo { public static synchronized void fun1(){ } public synchronized void fun2(){ } pub ...

  10. 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁

    什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...

随机推荐

  1. php中ajax跨域请求---小记

    php中ajax跨域请求---小记   前端时间,遇到的一个问题,情况大约是这样: 原来的写法: 前端js文件中: $.ajax({ type:'get', url:'http://wan.xxx.c ...

  2. 1763 An Essay towards solving a Problem in the Doctrine of Chances

    https://en.wikipedia.org/wiki/An_Essay_towards_solving_a_Problem_in_the_Doctrine_of_Chances

  3. java RMI

    import java.rmi.*; public interface Hello extends Remote { public String getGreeting() throws Remote ...

  4. SQLServer2008:助您轻松编写T-SQL存储过程(原创)【转】

      本文主要介绍 SQLServerExpress2008不用第三方工具调试T-SQL语句,经过本文的介绍,用SQLSERVER2008 Manage studio 编写.调试T-SQL存储过程都将是 ...

  5. sql 语句查询练习题

    1. 查询Student表中的所有记录的Sname.Ssex和Class列. select sname,ssex,class from student 2. 查询教师所有的单位即不重复的Depart列 ...

  6. Bluetooth Baseband介绍

    目录 1. 概述 1.1 Clock(时钟) 1.2 寻址方式 2. 物理信道(Physical Channels) 3. 物理链路(Physical Links) 4. 逻辑传输层(Logical ...

  7. 蓝牙HID协议笔记

    1.概述     The Human Interface Device (HID)定义了蓝牙在人机接口设备中的协议.特征和使用规程.典型的应用包括蓝牙鼠标.蓝牙键盘.蓝牙游戏手柄等.该协议改编自USB ...

  8. maven--composer---setting.xml(updatepolicy)---mvn install , mvn deploy

    场景:最近再整系统的自动部署流程,由于公司的jar包在svn以及mvn的仓库上都存在,开发人员在开发的过程中都依赖mvn仓库中的Jar 包,在jar上线的时候,配置管理人员把jar 从svn管理的工作 ...

  9. centos常用命令

    应用程序->附件->终端 一:使用CentOS常用命令查看cpumore /proc/cpuinfo | grep "model name"   grep " ...

  10. FastDFS分布式文件系统安装与使用(单节点)

    http://blog.csdn.net/xyang81/article/details/52837974 http://download.csdn.net/detail/xyang81/966749 ...