目录
Frist: Runnable创建实例
编写Java应用程序实现如下功能:第一个线程生成一个随机数,第二个线程每隔一段时间读取第一个线程生成的随机数,并判断它是否是奇数。要求采用实现Runnable接口和Thread类的构造方法的方式创建线程,而不是通过Thread类的子类的方式。
。
package core;
public class TestPrintNumberChar
{
public static void main(String args[])
{
// ---
String threadNamePrintNumber = "printNumber";
String threadNamePrintChar = "printChar";
PrintNumberChar printNumberChar
= new PrintNumberChar(threadNamePrintNumber, threadNamePrintChar);
// ---
Thread threadPrintNumber = new Thread(printNumberChar);
threadPrintNumber.setName(threadNamePrintNumber);
// ---
Thread threadPrintChar = new Thread(printNumberChar);
threadPrintChar.setName(threadNamePrintChar);
// ---
threadPrintNumber.start();
threadPrintChar.start();
}
}
class PrintNumberChar implements Runnable
{
// ---
private boolean flagNumberFirst = true;
private int numberIndex = 1;
private int charIndex = 1;
// ---
private String threadNamePrintNumber, threadNamePrintChar;
PrintNumberChar(String threadNamePrintNumber, String threadNamePrintChar)
{
this.threadNamePrintNumber = threadNamePrintNumber;
this.threadNamePrintChar = threadNamePrintChar;
}
// ---
public synchronized void printNumber()
{
while(numberIndex<=26)
{
if(flagNumberFirst)
{
System.out.print(numberIndex);
numberIndex++;
flagNumberFirst = false;
this.notify(); // this.notifyAll();
}
try
{
wait();
}
catch (InterruptedException e) {}
}
}
// ---
public synchronized void printChar()
{
while(charIndex<=26)
{
if(!flagNumberFirst)
{
System.out.print((char)('A'+charIndex-1));
charIndex++;
flagNumberFirst = true;
this.notify(); // this.notifyAll();
}
try
{
wait();
}
catch (InterruptedException e) {}
}
}
// ---
public void run() // public synchronized void run()
{
if(Thread.currentThread().getName().equals(threadNamePrintNumber))
{
printNumber();
}
else if(Thread.currentThread().getName().contentEquals(threadNamePrintChar))
{
printChar();
}
}
}
Second:线程通信
编写Java应用程序实现如下功能:第一个线程输出数字1-26,第二个线程输出字母A-Z,输出的顺序为1A2B3C...26Z,即每1个数字紧跟着1个字母的方式。要求线程间实现通信。要求采用实现Runnable接口和Thread类的构造方法的方式创建线程,而不是通过Thread类的子类的方式。
package modification;
/**
* 编写Java应用程序实现如下功能:
* 第一个线程输出数字1-26,第二个线程输出字母A-Z,
* 输出的顺序为1A2B3C...26Z,即每1个数字紧跟着1个字母的方式。
* 要求线程间实现通信。
* 要求采用实现Runnable接口和Thread类的构造方法的方式创建线程,而不是通过Thread类的子类的方式。
*/
public class TestPrintNumberCharLearning {
public static void main(String[] args) {
// ---
String threadNamePrintNumber = "printNumber";
String threadNamePrintChar = "printChar";
PrintNumberChar printNumberChar
= new PrintNumberChar( threadNamePrintNumber, threadNamePrintChar );
// ---
Thread threadPrintNumber = new Thread(printNumberChar);
}
}
class PrintNumberChar implements Runnable {
// member variates
private boolean flagNumberFirst = true;
private int numberIndex = 1;
private int charIndex = 1;
// ---
private String threadNamePrintNumber ,threadNamePrintChar;
PrintNumberChar( String threadNamePrintNumber, String threadNamePrintChar ) {
this.threadNamePrintNumber = threadNamePrintNumber;
this.threadNamePrintChar = threadNamePrintChar;
}
// ---
public synchronized void printNumber() {
while ( numberIndex <= 26 ) {
if ( flagNumberFirst ) {
System.out.print(numberIndex);
numberIndex++;
flagNumberFirst = false;
this.notify();
}
try {
wait();
} catch (InterruptedException e) {
}
}
}
// ---
public synchronized void printChar() {
while (charIndex <= 26) {
if ( !flagNumberFirst ) {
System.out.print( (char)('A' + charIndex - 1) );
charIndex++;
flagNumberFirst = true;
this.notify();
}
try {
wait();
} catch (InterruptedException e) {
}
}
}
/**
* public synchronized void run()
*/
@Override
public void run() {
if (Thread.currentThread().getName().equals( threadNamePrintChar )) {
printNumber();
}
else if (Thread.currentThread().getName().contentEquals( threadNamePrintChar )) {
printChar();
}
}
}
Third:银行存取问题
创建工作线程,模拟银行现金账户存款操作。多个线程同时执行存款操作时,如果不使用同步处理,会造成账户余额混乱,要求使用syncrhonized关键字同步代码块,以保证多个线程同时执行存款操作时,银行现金账户存款的有效和一致。要求采用实现Runnable接口和Thread类的构造方法的方式创建线程,而不是通过Thread类的子类的方式。
package modification;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Demand:
* 编写Java应用程序实现如下功能:
* 创建工作线程,模拟银行现金账户存款操作。
* 多个线程同时执行存款操作时,如果不使用同步处理,会造成账户余额混乱,
* 要求使用syncrhonized关键字同步代码块,以保证多个线程同时执行存款操作时,
* 银行现金账户存款的有效和一致。
* 要求采用实现Runnable接口和Thread类的构造方法的方式创建线程,
* 而不是通过Thread类的子类的方式。
*/
public class TestAccountLearning {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
executorService.execute(new AccountDeposit());
}
}
}
// --- ---
class Account {
private int balance = 0;
public int getBalance() {
return balance;
}
public synchronized void deposit(int amount) {
balance += amount;
System.out.println(balance);
}
}
class AccountDeposit implements Runnable {
// --- ---
private static Account account = new Account();
// ---
@Override
public void run() {
account.deposit(1);
}
}
MySolutions:
Bank.java:
package core.java.Bank;
import java.util.Arrays;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Bank {
private final double[] accounts ;
private Lock bankLock;
private Condition sufficientFunds;
public Bank(int n, double initialBalance) {
accounts = new double[n];
Arrays.fill(accounts, initialBalance);
bankLock = new ReentrantLock();
sufficientFunds = bankLock.newCondition();
}
public void transfer(int from, int to, double amount) throws InterruptedException {
bankLock.lock();
try {
while (accounts[from] < amount) {
sufficientFunds.await();
}
System.out.print(Thread.currentThread());
accounts[from] -= amount;
System.out.printf(" %10.2f from %d to %d", amount, from, to);
accounts[to] += amount;
System.out.printf("Total Balance: %10.2f%n", getTotalBalance());
sufficientFunds.signalAll();
} finally {
bankLock.unlock();
}
}
public double getTotalBalance() {
bankLock.lock();
try {
double sum = 0;
for (double a : accounts) {
sum += a;
}
return sum;
} finally {
bankLock.unlock();
}
}
public int size() {
return accounts.length;
}
}
Main.java
package four;
public class Main {
public static void main(String args[]) {
final Bank bank = new Bank();
Thread deposit = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bank.deposit(100);
bank.checkBalance();
}
}
});
Thread withdraw = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
bank.withdraw(100);
bank.checkBalance();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
withdraw.start();
deposit.start();
}
}
Temp-----