现在的绝大多数应用程序都是多线程的程序,而当有两个或两个以上的线程需要对同一数据进行存取时,就会出现条件竞争,也即

是这几个线程中都会有一段修改该数据状态的代码。但是如果这些线程的运行顺序推行不当的话是很容易造成死锁现象的。所以在JAVA中为

了防止出现这种现象的出现就产生了锁和条件机制用来对实现各个线程之间互斥的去访问这段临界区的代码,唉!由于我也是才刚学多线程

并发编程,也不可能有多深多深的理解,所以就先只写一下它们的用法了。

------------------YYC

其实从JAVA SE 5.0以后就有两种机制来防止代码块受并发访问的干扰,一种是通过lock机制,另一种是通过synchronized来实现,

下面分别来实现。

该部分程序的功能主要是实现通过多个线程 去访问yy和cc这两个变量,然后在每个线程中都分别不断的从其中一个大于0 的变量中减去10,然

后在给另外的一个变量加上10,如果说此处不用锁的机制去实现线程的修改yy和cc时,是恒容易发生死锁错误的,而且在运行一段时间后yy和cc

的总和也将不再是100.

方法一:

public int  yy = 0;
public int cc =100;
public class YYThread extends Thread{
private Condition condition ; //定义条件对象
private Lock YYlock = new ReentrantLock(); //定义锁对象,
//其中ReentrantLock()方法是用来构造一个用来保护临界区的可以重入锁,此处也可以调用ReentrantLock(boolean fair)来构造一个公平锁 @Override
public void run() {
// TODO Auto-generated method stub
super.run();
YYlock.lock();//当线程运行到这个地方时给下面的代码片加上互斥锁
condition = YYlock.newCondition(); //初始化条件对象
Random random = new Random();
int a = random.nextInt();
int b = a%2;
if(b==0)
{
if(yy<10)
{try {
condition.await();//当发现该线程的条件不足时,自动阻塞当前线程,并释放处理机等资源和解锁临界资源
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
yy-=10;
cc+=10;
Log.d("yy "+yy, "cc "+cc);
condition.signalAll();//当资源状态改变时,调用该方法解除所有因这一条件而等待的所有线程,当这些线程从等待集里移除时。它们就
//再次成为可运行的,相当于是处于就绪状态,调度器就可再次激活他们。
}
else {
if(cc<10)
{try {
condition.await();
//当发现该线程的条件不足时,自动阻塞当前线程,并释放处理机等资源和解锁临界资源
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
yy+=10;
cc-=10;
Log.d("yy "+yy, "cc "+cc);
condition.signalAll();//激活其他线程
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();}
finally{
YYlock.unlock();
//解锁对该部分代码的访问控制,注意此解锁操作必须要放在finally字句里面,因为如果临界区的代码抛出异常的话,锁必须要被
//释放,否则其他所有线程都将永远阻塞 } } }

调用部分

//实现方式一:
for(int i =0 ;i<80;i++)
{
YYThread yt = new YYThread();
yt.start();
}

成功实现锁和条件的机制锁主要是原来实现保护临界区的代码片,实现互斥的相互访问
条件主要是用来管理进入临界区的线程condition.await();进入条件的等待集, 该线程被阻塞,

并自动放弃处理机资源和解锁临界资源,但它与互斥阻塞的主要区别是只要
当condition.signalAll();激活该该线程时,该线程将立马成为可运行的,并接受调度器的调度。
YYlock.lock();互斥阻塞,当获得临界资源时才可能被执行

方法二:

定义该方法

public int  yy = 0;
public int cc =100;
private synchronized void fun()//用关键字synchronized声明为该方法只能互斥访问
{ Random random = new Random();
int a = random.nextInt();
int b = a%2;
if(b==0)
{
while(yy<10)
{try {
wait();//条件阻塞
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
yy-=10;
cc+=10;
notifyAll();//激活阻塞队列的线程
Log.d("yy "+yy, "cc "+cc);
}
else {
while(cc<10)
{try {
wait();//用while循环检测条件,但也会遵循“让权等待”的原则。
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
cc-=10;
yy+=10;
notifyAll();//激活阻塞队列的线程
Log.d("yy "+yy, "cc "+cc);
}
}

定义线程

public class YYThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run(); fun(); }
}

开启线程

			for(int i =0 ;i<80;i++)
{
YYThread yt = new YYThread();
yt.start();
}

其实方法一和方法二的效果都是一样的,但是我们可以看到使用synchronized关键字来编写代码要简洁的多,但是如果你要理解这一关键字的机制,你就必须了解

其实每一个对象都是有一个内部锁的,并且该锁有一个内部条件,由锁来管理那些试图进入synchronized方法的线程,由条件来管理那些调用wait的线程。

以Android环境为例的多线程学习笔记(二)-----------------锁和条件机制的更多相关文章

  1. 多线程学习笔记二之JUC组件

    目录 概述 JUC锁框架图 使用内置锁还是JUC显示锁? 概述   为了对共享资源提供更细粒度的同步控制,JDK5新增了java.util.concurrent(JUC)并发工具包,并发包新增了Loc ...

  2. 多线程学习笔记(二) BackgroundWorker 和 ProgressChanged

    BackgroundWorker是在内部使用了线程池的技术:同时,在Winform 或WPF编码中,它还给工作线程和UI线程提供了交互的能力. Thread和ThreadPool默认都没有提供这种交互 ...

  3. 微信小程序学习笔记二 列表渲染 + 条件渲染

    1. 列表渲染 1.1 wx:for 在组件上使用wx:for控制属性绑定一个数组, 即可使用数组中各项的数据重复渲染该组件 默认数组的当前项的下标变量名默认为 index, 数组当前项的变量名默认为 ...

  4. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  5. [转]phoneGap3.0安装步骤(以windows下的android环境为例):

    phoneGap3.0安装步骤(以windows下的android环境为例): 环境: WIN系统,JDK,Android,Eclipse,Ant,Git,PhoneGap3.x (Cordova) ...

  6. Java多线程学习(二)synchronized关键字(1)

    转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...

  7. Java多线程学习(二)synchronized关键字(2)

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  8. Android M Permission 运行时权限 学习笔记

    Android M Permission 运行时权限 学习笔记 从Android 6.0开始, 用户需要在运行时请求权限, 本文对运行时权限的申请和处理进行介绍, 并讨论了使用运行时权限时新老版本的一 ...

  9. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...

随机推荐

  1. DDL

    在DDL(Data Definition Language)中,创建.删除.修改使用create.drop.alter关键字 数据库的创建 create database 数据库名选择数据库 use ...

  2. SQL Server执行计划那些事儿(1)——哈希、合并、嵌套联接的选择

    接下来的文章是记录自己曾经的盲点,同时也透漏了自己的发展历程(可能发展也算不上,只能说是瞎混).当然,一些盲点也在工作和探究过程中慢慢有些眉目,现在也愿意发扬博客园的奉献精神,拿出来和大家分享一下. ...

  3. some knowledge

    注意 关于cornerstone无法上传library文件的问题  上面是我要添加的library文件,网上提供的方法是 在CornerStone的菜单栏里面 View->ShowIgnoreI ...

  4. TCP/IP详解之:ARP协议 和 RARP协议

    ARP功能:从逻辑internet地址(IP地址)到对应的物理硬件地址(以太网地址)之间的转换 ARP工作原理: (1)首先每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP和MAC间的 ...

  5. PHP Curl CURLOPT_POSTFIELDS 1024

    resolve : curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); url: http://www.laruence.com/2011/ ...

  6. jsp获取枚举的值

    Struts2的Action传回页面一个list,页面迭代这个list,获取下拉框的值,获取过来是枚举类型. 在jsp页面获取枚举的常量值和枚举的值的例子如下: jsp页面: <td >状 ...

  7. EditText 默认不获取焦点,弹出软键盘布局变形解决方案

    关于弹出软键盘布局变形解决方案: 在androidMainfest.xml文件中在此Activity中写入 android:windowSoftInputMode="adjustPan&qu ...

  8. sass和compass安装

    安装Sass和Compass sass基于Ruby语言开发而成,因此安装sass前需要安装Ruby.(注:mac下自带Ruby无需在安装Ruby!) window下安装SASS首先需要安装Ruby,先 ...

  9. Nand ECC校验和纠错原理及2.6.27内核ECC代码分析

    ECC的全称是Error Checking and Correction,是一种用于Nand的差错检测和修正算法.如果操作时序和电路稳定性不存在问题的话,NAND Flash出错的时候一般不会造成整个 ...

  10. 关于ajax中async参数的感悟

    async,这个参数默认为true. 就是异步去处理信息. 当把它设置为false的时候,就是同步去处理数据了. var current_lead_id = '<?php echo $curre ...