java线程个人总结

来源:互联网 发布:淘宝千人千面规则 编辑:程序博客网 时间:2024/05/16 13:01

最近,正学习java线程,总结如下:

java.util.concurrent.locks.Lock

void lock() 获得这个锁,如果这个锁当前被另一个线程所持有,则该线程发生阻塞。

void unlock() 释放锁定。

java.util.concurrent.locks.ReentrantLock

public ReentrantLock() 创建一个可被用来保护临界区的可重人锁。

用ReentrantLock保护代码块的基本结构如下:

myLock.lock(); // ReentrantLock对象 

try

{

     // 临界区

}

finally

{

     myLock.unlock(); // 确保锁能够释放

}

该结构保证在任何时刻只有一个线程能够进入临界区。一旦一个线程锁住了锁对象,其他任何线程都无法通过lock语句。当其他线程调用lock时,它们会被阻塞,直到第一线程释放锁对象。

使用Lock和Condition对象的关键点:

     1.锁用来保护代码片段,任何时刻只允许一个线程执行被保护的代码。

     2.锁可以管理试图进入被保护代码段的线程。

     3.锁可以拥有一个或多个相关的条件对象。

     4.每个条件对象管理那些已进入被保护代码段但还不能运行的线程。

Condition有两个方法可以唤醒等待线程:signalAll()方法和signal()方法。

signalAll()方法唤醒所有等待线程,该方法不会立即激活等待线程,它只是解除等待线程的阻塞状态,这样这些线程就可以在当前线程退出同步方法后,通过竞争获得对对象的访问。

而signal()方法则是随机解除等待集中某个线程的阻塞状态。该方法存在一定的危险,如果被随机选中的线程发现自己还是无法运行,它会再次被阻塞。如果没有任何其他线程再次调用singal()方法,那么系统就死锁了。

当一个线程调用await()方法时,它无法自己解除阻塞状态。它把自己的命运交给了其他线程。如果没有任何其他线程来解除等待线程的阻塞状态,它就永远也不会运行了,这会导致死锁。

例程1:SynchBankTest.java
public class TestSync implements Runnable {     Timer timer = new Timer();     public static void main(String[] args)     {          TestSync test = new TestSync();          Thread t1 = new Thread(test);          Thread t2 = new Thread(test);          t1.setName("t1");          t2.setName("t2");          t1.start();          t2.start();     }     public void run() {          timer.add(Thread.currentThread().getName());     }}class Timer {     private static int num = 0;     public /*synchronized*/ void add(String name) {          synchronized (this) {               num++;               try {                    Thread.sleep(1);               }               catch (InterruptedException e)               {               }               System.out.println(name + ", 你是第" + num + "个使用timer的线程");          }     }}


 

例程1:SynchBankTest.java
import java.util.concurrent.locks.*;/*** This program shows how multiple threads can safely access a data structure.*/public class SynchBankTest{     public static void main(String[] args)     {          Bank b = new Bank(NACCOUNTS, INITIAL_BALANCE);          int i;          for (i = 0; i < NACCOUNTS; i++)          {               TransferRunnable r = new TransferRunnable(b, i, INITIAL_BALANCE);               Thread t = new Thread(r);               t.start();          }     }     public static final int NACCOUNTS = 100;     public static final double INITIAL_BALANCE = 1000;}/*** A bank with a number of bank accounts.*/class Bank{     /**     * Constructs the bank.     * @param n the number of accounts     * @param initialBalance the initial balance     * for each account     */     public Bank(int n, double initialBalance)     {          accounts = new double[n];          for (int i = 0; i < accounts.length; i++)               accounts[i] = initialBalance;          bankLock = new ReentrantLock();          sufficientFunds = bankLock.newCondition();     }     /**     * Transfers money from one accounts to another.     * @param from the account to transfer from     * @param to the account to transfer to     * @param amount the amount to transfer     */     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();          }     }     /**     * Gets the sum of all account balances.     * @return the total balance     */     public double getTotalBalance()     {          bankLock.lock();          try          {               double sum = 0;               for (double a : accounts)                    sum += a;               return sum;          }          finally          {               bankLock.unlock();          }     }     /**     * Gets the number of accounts in the bank.     * @return the number of accounts     */     public int size()     {          return accounts.length;     }     private final double[] accounts;     private Lock bankLock;     private Condition sufficientFunds;}/*** A runnable that transfers money from an account to other* accounts in a bank.*/class TransferRunnable implements Runnable{     /**     * Constructs a transfer runnable.     * @param b the bank between whose account money is transferred     * @param from the account to transfer money from     * @pram max the maximum amount of money in each transfer     */     public TransferRunnable(Bank b, int from, double max)     {          bank = b;          fromAccount = from;          maxAmount = max;     }     public void run()     {          try          {               while (true)               {                    int toAccount = (int) (bank.size() * Math.random());                    double amount = maxAmount * Math.random();                    bank.transfer(fromAccount, toAccount, amount);                    Thread.sleep((int) (DELAY * Math.random()));               }          }          catch (InterruptedException e) {}     }     private Bank bank;     private int fromAccount;     private double maxAmount;     private int repetitions;     private int DELAY = 10;}

 

原创粉丝点击