執行緒通訊和同步的兩種實現方…
阿新 • • 發佈:2019-02-14
在多執行緒程式設計中,不免要涉及同步和通訊兩個方面。同步有兩種方法實現,一種是利用synchronized標示,另外一種是加鎖。生成鎖的物件的方法是:private
static Lock lock = new
ReentrantLock();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 1ttThread2ttBalance");
}
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("ttwithdraw " + amount + "tt"
+ 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 + "tttt"
+ 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 1ttThread2ttBalance");
}
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("ttwithdraw " + amount + "tt"
+ 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 + "tttt"
+ getBalance());
// newDeposite.signalAll();
super.notify();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
// lock.unlock();
}
}
}
}