Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。

package java_thread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class LockTest { /**
* @param args
*/
public static void main(String[] args) {
new LockTest().init();
} private void init(){
final Outputer outputer = new Outputer();
new Thread(new Runnable(){
@Override
public void run() {
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output("zhangxiaoxiang");
} }
}).start(); new Thread(new Runnable(){
@Override
public void run() {
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output("lihuoming");
} }
}).start(); } static class Outputer{
Lock lock = new ReentrantLock();
public void output(String name){
int len = name.length();
lock.lock();
try{
for(int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}finally{
lock.unlock();
}
} public synchronized void output2(String name){
int len = name.length();
for(int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
} public static synchronized void output3(String name){
int len = name.length();
for(int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}

读写锁:分为读锁写锁多个读锁不互斥读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁

package java_thread;

import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockTest {
public static void main(String[] args) {
final Queue3 q3 = new Queue3();
for(int i=0;i<3;i++)
{
new Thread(){
public void run(){
while(true){
q3.get();
}
} }.start(); new Thread(){
public void run(){
while(true){
q3.put(new Random().nextInt(10000));
}
} }.start();
} }
} class Queue3{
private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
ReadWriteLock rwl = new ReentrantReadWriteLock();
public void get(){
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " be ready to read data!");
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName() + "have read data :" + data);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwl.readLock().unlock();
}
} public void put(Object data){ rwl.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " be ready to write data!");
Thread.sleep((long)(Math.random()*1000));
this.data = data;
System.out.println(Thread.currentThread().getName() + " have write data: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwl.writeLock().unlock();
} }
}

 读的时候可以被读打断,写的时候不能太打断

Condition的功能类似在传统线程技术中的Object.wait()和Object.notify()的功能。在等待 Condition 时,允许发生“虚假唤醒”,这通常作为对基础平台语义的让步。对于大多数应用程序,这带来的实际影响很小,因为 Condition 应该总是在一个循环中被等待,并测试正被等待的状态声明。某个实现可以随意移除可能的虚假唤醒,但建议应用程序程序员总是假定这些虚假唤醒可能发生,因此总是在一个循环中等待。

一个锁内部可以有多个Condition,即有多路等待和通知,可以参看jdk1.5提供的Lock与Condition实现的可阻塞队列的应用案例,从中除了要体味算法,还要体味面向对象的封装。在传统的线程机制中一个监视器对象上只能有一路等待和通知,要想实现多路等待和通知,必须嵌套使用多个同步监视器对象。(如果只用一个Condition,两个放的都在等,一旦一个放的进去了,那么它通知可能会导致另一个放接着往下走。)

package java_thread;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class ConditionCommunication {
public static void main(String[] args) {
final Business business = new Business();
new Thread(
new Runnable() {
@Override
public void run() {
for(int i=1;i<=50;i++){
business.sub(i);
}
}
}
).start(); for(int i=1;i<=50;i++){
business.main(i);
} } static class Business {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
private boolean bShouldSub = true; public void sub(int i){
lock.lock();
try{
while(!bShouldSub){
try {
condition.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=1;j<=5;j++){
System.out.println("sub thread sequence of " + j + ",loop of " + i);
}
bShouldSub = false;
condition.signal();
}finally{
lock.unlock();
}
} public void main(int i){
lock.lock();
try{
while(bShouldSub){
try {
condition.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=1;j<=10;j++){
System.out.println("main thread sequence of " + j + ",loop of " + i);
}
bShouldSub = true;
condition.signal();
}finally{
lock.unlock();
}
}
} }

Java多线程——Lock&Condition的更多相关文章

  1. 玩转Java多线程(Lock.Condition的正确使用姿势)

    转载请标明博客的地址 本人博客和github账号,如果对你有帮助请在本人github项目AioSocket上点个star,激励作者对社区贡献 个人博客:https://www.cnblogs.com/ ...

  2. java多线程Lock接口简介使用与synchronized对比 多线程下篇(三)

    前面的介绍中,对于显式锁的概念进行了简单介绍 显式锁的概念,是基于JDK层面的实现,是接口,通过这个接口可以实现同步访问 而不同于synchronized关键字,他是Java的内置特性,是基于JVM的 ...

  3. Java多线程Lock

    JDK5以后为代码的同步提供了更加灵活的Lock+Condition模式,并且一个Lock可以绑定多个Condition对象 1.把原来的使用synchronized修饰或者封装的代码块用lock.l ...

  4. java 多线程 day13 condition 线程通信

    /** * Created by chengtao on 17/12/5. * Condition 类似 wait和notify,解决线程间的同步问题 */ import java.util.conc ...

  5. java多线程-Lock

    大纲: Lock接口 synchronized&Lock异同 一.Lock public interface Lock { void lock(); void lockInterruptibl ...

  6. java多线程lock的使用

    看代码: package com.ming.thread.reentrantlock; import java.util.concurrent.locks.Lock; import java.util ...

  7. Java多线程系列--“JUC锁”06之 Condition条件

    概要 前面对JUC包中的锁的原理进行了介绍,本章会JUC中对与锁经常配合使用的Condition进行介绍,内容包括:Condition介绍Condition函数列表Condition示例转载请注明出处 ...

  8. Java多线程编程核心技术--Lock的使用(一)

    使用ReentrantLock类 在Java多线程中,可以使用synchronized关键字来实现线程之间的同步互斥,但在JDK1.5中新增加了ReentrantLock类也能达到同样的效果,并且在扩 ...

  9. Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock

    在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(Reentrant ...

随机推荐

  1. 【php】https请求

    /** * 模拟提交参数,支持https提交 可用于各类api请求 * @param string $url : 提交的地址 * @param array $data :POST数组 * @param ...

  2. 【FindReport】图表快速部署开发

    在线帮助文档:http://help.finereport.com/ 开发部署环境:Java Tomcat 数据可视化工具 大屏动态显示

  3. jetty debug 启动 jettyconfig配置文件

    jetty 代码启动 debug很简单  run----->>>debug as  代码启动配置文件 start 方法 @Test public void serverStrart( ...

  4. Python3机器学习—Tensorflow数字识别实践

    [本文出自天外归云的博客园] Windows下Anaconda+Tensorflow环境部署 1. 安装Anaconda. 2. 开始菜单 > 所有程序 > Anaconda 3 (64- ...

  5. Asp.net 从客户端中检测到有潜在危险的Request.Form值

    解决方法: 在Web.config文件里找到<httpRuntime>节点,然后修改requestValidationMode="2.0" 修改结果如下: <sy ...

  6. JAVA-JSP内置对象之request获得所有的参数名称

    相关资料:<21天学通Java Web开发> 获得所有的参数名称1.request对象的getParameterNames()方法可以获得所有的参数名称. RequestForm2.jsp ...

  7. 解决sql server不允许保存表结构修改的问题

    说明(2017-5-25 15:38:09):

  8. 解决MYSQL ERROR 1045 (28000)问题

    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)   Red Hat Enterpr ...

  9. 【转】无后端(nobackend):前端优先的Web开发【译】

    每个应用都由两样东西构成:该应用独有的功能和所有应用共有的功能,比方说用户注册.登录.忘记密码等.而从用户的角度出发,那些独有的功能归结起来就是用户界面以及系统的行为模式.而在视觉表象之后的功能,用户 ...

  10. java IO【转】

    Java 流在处理上分为字符流和字节流.字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符.字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组. Java 内用 U ...