Java 并发编程学习笔记(1)--线程的同步1
2018-01-18 21:32
155 查看
多线程程序中,经常会遇到多个线程需要共享一对数据的存取。当两个线程存取相同的对象,并且每一个线程都调用了一个修改该对象状态的方法,可能导致讹误。这样的情况称为竞争条件。
1.使用ReentrantLock保护代码块
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[] account ;
private Lock banklock ;
private Condition suffcientFunds;
public bank(int n,double initialBlance){
account = new double
;
Arrays.fill(account,initialBlance);
banklock = new ReentrantLock(); //声明一个显示锁
}
public void transfer(int from, int to,double amount)
{
banklock.lock();
//在共享资源前 发布线程 锁
try
{
System.out.println(Thread.currentThread());
account[from] -= amount;
System.out.printf("%10.2f from %d to %d",amount,from,to);
account[to] += amount;
System.out.printf("Total Balance :%10.2f%n",getTotalBlance());
}
catch (Exception e)
{
}
finally {
{
banklock.unlock();
//加锁同样需要解锁
}
}
}
public double getTotalBlance()
{
banklock.lock();
try {
double sum =0;
for (double a:account)sum+=a;
return sum;
}
finally {
banklock.unlock();
}
}
public int size()
{
return account.length;
}
}
以上的程序中,每一个bank对象有自己的ReentrantLock对象。如果两个线程试图访问同一个Bank对象,锁就以串行方式提供服务。但是如果两个线程访问不同bank对象,每个线程得到不同的对象锁,两个线程就不会阻塞。2.条件对象
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[] account ;
private Lock banklock ;
private Condition suffcientFunds;
public bank(int n,double initialBlance){
account = new double
;
Arrays.fill(account,initialBlance);
banklock = new ReentrantLock(); //声明一个显示锁
suffcientFunds = banklock.newCondition(); //条件锁
}
public void transfer(int from, int to,double amount)
{
banklock.lock();
//在共享资源前 发布线程 锁
try
{
while(account[from]<amount)
suffcientFunds.await();
//条件锁
System.out.println(Thread.currentThread());
account[from] -= amount;
System.out.printf("%10.2f from %d to %d",amount,from,to);
account[to] += amount;
System.out.printf("Total Balance :%10.2f%n",getTotalBlance());
suffcientFunds.signalAll();
//释放条件 等待
}
catch (Exception e)
{
}
finally {
{
banklock.unlock();
//加锁同样需要解锁
}
}
}
public double getTotalBlance()
{
banklock.lock();
try {
double sum =0;
for (double a:account)sum+=a;
return sum;
}
finally {
banklock.unlock();
}
}
public int size()
{
return account.length;
}
}
线程进入临界去后,通常会发现在满足某一条件后才会执行。一个锁对象可以有一个或者多个相关对象。可以用newCondition方法获得一个条件对象。调用await方法,会阻塞当前线程,会进入该条件的等待集。当锁可用时,该线程不能马上接触阻塞,要等待其他线程调用同意条件上的signalAllwhile(!ok)condition.await 采用这样的形式。
3.synchronized关键词
一个方法调用该关键词,对象的锁将保护整个方法。内部对象锁只有一个相关条件。wait方法添加一个线程到等待集中,notifyALL/notify方法解除等待线程的阻塞状态。
package com.qunar.com.www;
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[] account ;
private Lock banklock ;
private Condition suffcientFunds;
public bank(int n,double initialBlance){
account = new double
;
Arrays.fill(account,initialBlance);
banklock = new ReentrantLock(); //声明一个显示锁
suffcientFunds = banklock.newCondition(); //条件锁
}
public synchronized void transfer(int from, int to,double amount)
{
try
{
while(account[from]<amount)
wait();
//条件锁
System.out.println(Thread.currentThread());
account[from] -= amount;
System.out.printf("%10.2f from %d to %d",amount,from,to);
account[to] += amount;
System.out.printf("Total Balance :%10.2f%n",getTotalBlance());
notifyAll();
//释放条件 等待
}
catch (Exception e)
{
}
finally {
{
}
}
}
public double getTotalBlance()
{
banklock.lock();
try {
double sum =0;
for (double a:account)sum+=a;
return sum;
}
finally {
banklock.unlock();
}
}
public int size()
{
return account.length;
}
}
1.使用ReentrantLock保护代码块
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[] account ;
private Lock banklock ;
private Condition suffcientFunds;
public bank(int n,double initialBlance){
account = new double
;
Arrays.fill(account,initialBlance);
banklock = new ReentrantLock(); //声明一个显示锁
}
public void transfer(int from, int to,double amount)
{
banklock.lock();
//在共享资源前 发布线程 锁
try
{
System.out.println(Thread.currentThread());
account[from] -= amount;
System.out.printf("%10.2f from %d to %d",amount,from,to);
account[to] += amount;
System.out.printf("Total Balance :%10.2f%n",getTotalBlance());
}
catch (Exception e)
{
}
finally {
{
banklock.unlock();
//加锁同样需要解锁
}
}
}
public double getTotalBlance()
{
banklock.lock();
try {
double sum =0;
for (double a:account)sum+=a;
return sum;
}
finally {
banklock.unlock();
}
}
public int size()
{
return account.length;
}
}
import java.util.*; import java.lang.*; public class main { public static final int NACCOUNTS = 100; public static final double INTIAL_BLANCE = 1000; public static final double MAX_AMOUNT =1000; public static final int Dealay =10; public static void main(String[] args) { bank aim1 = new bank(NACCOUNTS,INTIAL_BLANCE); //一共会开启100个线程 每个账户是一个线程 会随机给其余账户打钱 for (int i =0;i<NACCOUNTS;i++) { int fromAccount = i; Runnable r = () ->{ try { while(true) { int toAcccount = (int)(aim1.size()*Math.random()); double amount = MAX_AMOUNT*Math.random(); aim1.transfer(fromAccount,toAcccount,amount); Thread.sleep((int) (Dealay * Math.random())); } }catch (InterruptedException e) { } }; Thread t = new Thread(r); t.start(); } } }
以上的程序中,每一个bank对象有自己的ReentrantLock对象。如果两个线程试图访问同一个Bank对象,锁就以串行方式提供服务。但是如果两个线程访问不同bank对象,每个线程得到不同的对象锁,两个线程就不会阻塞。2.条件对象
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[] account ;
private Lock banklock ;
private Condition suffcientFunds;
public bank(int n,double initialBlance){
account = new double
;
Arrays.fill(account,initialBlance);
banklock = new ReentrantLock(); //声明一个显示锁
suffcientFunds = banklock.newCondition(); //条件锁
}
public void transfer(int from, int to,double amount)
{
banklock.lock();
//在共享资源前 发布线程 锁
try
{
while(account[from]<amount)
suffcientFunds.await();
//条件锁
System.out.println(Thread.currentThread());
account[from] -= amount;
System.out.printf("%10.2f from %d to %d",amount,from,to);
account[to] += amount;
System.out.printf("Total Balance :%10.2f%n",getTotalBlance());
suffcientFunds.signalAll();
//释放条件 等待
}
catch (Exception e)
{
}
finally {
{
banklock.unlock();
//加锁同样需要解锁
}
}
}
public double getTotalBlance()
{
banklock.lock();
try {
double sum =0;
for (double a:account)sum+=a;
return sum;
}
finally {
banklock.unlock();
}
}
public int size()
{
return account.length;
}
}
线程进入临界去后,通常会发现在满足某一条件后才会执行。一个锁对象可以有一个或者多个相关对象。可以用newCondition方法获得一个条件对象。调用await方法,会阻塞当前线程,会进入该条件的等待集。当锁可用时,该线程不能马上接触阻塞,要等待其他线程调用同意条件上的signalAllwhile(!ok)condition.await 采用这样的形式。
3.synchronized关键词
一个方法调用该关键词,对象的锁将保护整个方法。内部对象锁只有一个相关条件。wait方法添加一个线程到等待集中,notifyALL/notify方法解除等待线程的阻塞状态。
package com.qunar.com.www;
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[] account ;
private Lock banklock ;
private Condition suffcientFunds;
public bank(int n,double initialBlance){
account = new double
;
Arrays.fill(account,initialBlance);
banklock = new ReentrantLock(); //声明一个显示锁
suffcientFunds = banklock.newCondition(); //条件锁
}
public synchronized void transfer(int from, int to,double amount)
{
try
{
while(account[from]<amount)
wait();
//条件锁
System.out.println(Thread.currentThread());
account[from] -= amount;
System.out.printf("%10.2f from %d to %d",amount,from,to);
account[to] += amount;
System.out.printf("Total Balance :%10.2f%n",getTotalBlance());
notifyAll();
//释放条件 等待
}
catch (Exception e)
{
}
finally {
{
}
}
}
public double getTotalBlance()
{
banklock.lock();
try {
double sum =0;
for (double a:account)sum+=a;
return sum;
}
finally {
banklock.unlock();
}
}
public int size()
{
return account.length;
}
}
相关文章推荐
- Java线程(八):锁对象Lock-同步问题更完美的处理方式
- java线程同步方法,方法块差别
- (转)Java线程:线程的同步与锁
- JAVA 线程 同步 信号量
- java 总结几种线程异步转同步的方法
- java 协调同步的线程
- JAVA线程同步——消费者和生产者模式
- java线程同步锁优化
- java多线程之线程的同步与锁定(转)
- java线程同步和锁
- Java深度历险(三)——Java线程:基本概念、可见性与同步
- Java之线程安全中的三种同步方式
- Java线程同步lock和unlock的用法
- JAVA学习第二十四课(多线程(三))- 线程的同步
- Java多线程(3) 线程的同步-上
- java线程同步
- Java复习之线程的同步与死锁
- Java线程同步示例
- Java基础第十二天学习日记_线程、线程的同步、线程间通讯
- Java线程同步