在多线程编程中,不免要涉及同步和通讯两个方面。同步有两种方法实现,一种是利用synchronized标示,另外一种是加锁。生成锁的对象的方法是:privatestatic Lock lock = newReentrantLock();Lock是一个接口,而Reentrantlock是一个实现的类。构造方法有:ReentrantLock()和ReentrantLock(fair:boolean)两种。其中第二种传递的是一个boolean值的参数,当设置为true时系统会按照等待的先后时间让线程活得锁,但是效率和性能不如默认值的好,但是同时也可以避免资源匮乏。synchronized可以声明方法,也可以用来标记某段代码。用来标记某段代码时的用法是:synchronized(){}。
通讯方面有两种方法,第一种是利用锁生成Condition对象,然后调用await()和signal()或者signalall(),另外一种是利用继承的object类中的wait()和notify()或者notifyall()唤醒方法。个人觉得利用锁生成的condition对象的方法会比较灵活。下面是实现的存款和取款的小程序。第一种实现的方法是lock加condition:
package com.ccy.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadCooperation {
private static Account account = new Account();
public static void main(String[] args) {
ExecutorService executor =Executors.newFixedThreadPool(2);
executor.execute(new DepositeTask());
executor.execute(new WithdrawTask());
executor.shutdown();
System.out.println("Thread 1\t\tThread2\t\tBalance");
}
private static class DepositeTask implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
try {
while (true) {
account.deposite((int) (Math.random() * 10) + 1);
Thread.sleep(1000);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
private static class WithdrawTask implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
account.withdraw((int) (Math.random() * 10) + 1);
}
}
}
private static class Account {
private static Lock lock = new ReentrantLock();
private static Condition newDeposite =lock.newCondition();
private int balance = 0;
public int getBalance() {
return this.balance;
}
public void withdraw(int amount) {
lock.lock();
try {
while (this.balance < amount) {
newDeposite.await();
//super.wait();
}
balance -= amount;
System.out.println("\t\twithdraw " + amount + "\t\t"
+ getBalance());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void deposite(int amount) {
lock.lock();
try {
balance += amount;
System.out.println("deposite:" + amount + "\t\t\t\t"
+ getBalance());
newDeposite.signal();
//super.notifyAll();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
第二种是synchronized加object对象中的wait和notify方法:
package com.ccy.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadCooperation2 {
private static Account account = new Account();
public static void main(String[] args) {
ExecutorService executor =Executors.newFixedThreadPool(2);
executor.execute(new DepositeTask());
executor.execute(new WithdrawTask());
executor.shutdown();
System.out.println("Thread 1\t\tThread2\t\tBalance");
}
private static class DepositeTask implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
try {
while (true) {
account.deposite((int) (Math.random() * 10) + 1);
Thread.sleep(1000);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
private static class WithdrawTask implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
account.withdraw((int) (Math.random() * 10) + 1);
}
}
}
private static class Account {
// private static Lock lock = new ReentrantLock();
//
// private static Condition newDeposite =lock.newCondition();
private int balance = 0;
public int getBalance() {
return this.balance;
}
public synchronized void withdraw(int amount) {
// lock.lock();
try {
while (this.balance < amount) {
// newDeposite.await();
super.wait();
}
balance -= amount;
System.out.println("\t\twithdraw " + amount + "\t\t"
+ getBalance());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// lock.unlock();
}
}
public synchronized void deposite(int amount) {
// lock.lock();
try {
balance += amount;
System.out.println("deposite:" + amount + "\t\t\t\t"
+ getBalance());
// newDeposite.signalAll();
super.notify();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
// lock.unlock();
}
}
}
}