Java多线程Lock

JDK5以后为代码的同步提供了更加灵活的Lock+Condition模式,并且一个Lock可以绑定多个Condition对象

1.把原来的使用synchronized修饰或者封装的代码块用lock.lock()与lock.unlock()进行手动的锁获取与释放

//原来的同步方式
synchronized (obj) {
	...
}

//JDK5.0新增的同步方式
//lock.unlock();建议最好要放在finally 执行
try {
	lock.lock();
	...
} finally {
	lock.unlock();
}

2.把原来线程之间的通讯方式由锁对线obj.wait()和obj.notify()改成了Condition对象的con.await()与con.signal()方法

如下用Lock的方式重写多生产者多消费者模式时,线程可以指定唤醒生产者或者消费者,这样拥有更高的效率与安全性

package jdk5lockDome;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author wpy
 *
 */
public class ProducerConsumer {
	public static void main(String[] args) {
		Resource resource = new Resource();

		Producer producer0 = new Producer(resource);
		Producer producer1 = new Producer(resource);

		Consumer consumer2 = new Consumer(resource);
		Consumer consumer3 = new Consumer(resource);

		Thread t0 = new Thread(producer0);
		Thread t1 = new Thread(producer1);
		Thread t2 = new Thread(consumer2);
		Thread t3 = new Thread(consumer3);

		t0.start();
		t1.start();

		t2.start();
		t3.start();

	}

}

class Producer implements Runnable {
	private Resource resource;

	public Producer(Resource resource) {
		this.resource = resource;
	}

	@Override
	public void run() {
		while (true) {
			resource.set("资源");
		}
	}
}

class Consumer implements Runnable {
	private Resource resource;

	public Consumer(Resource resource) {
		this.resource = resource;
	}

	@Override
	public void run() {
		while (true) {
			resource.out();
		}
	}
}

class Resource {
	private String name;
	private int count = 1;
	// 是否生成完毕
	private boolean flag = false;

	/**
	 * 互斥锁(同时只有一个线程拥有锁)
	 */
	private Lock lock = new ReentrantLock();
	private Condition producerCon = lock.newCondition();
	private Condition consumerCon = lock.newCondition();

	/**
	 * 生产方法
	 *
	 * @param name
	 */
	public void set(String name) {
		try {
			lock.lock();
			String threadName = Thread.currentThread().getName();
			while (flag) {
				System.out.println(threadName + "进入等待状态");
				producerCon.await();
			}
			System.out.println(threadName + "取得执行权");

			this.name = name + count;
			count++;
			System.out.println("生产者:" + this.name);
			flag = true;
			consumerCon.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	/**
	 * 消费方法
	 */
	public void out() {
		try {
			lock.lock();
			String threadName = Thread.currentThread().getName();
			while (!flag) {
				System.out.println(threadName + "进入等待状态");
				consumerCon.await();
			}
			System.out.println(threadName + "取得执行权");

			System.out.println("============消费者:" + name);
			flag = false;
			producerCon.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}

  

  

时间: 2024-10-12 03:06:49

Java多线程Lock的相关文章

Java多线程——Lock&Condition

Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. package java_thread; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockTest { /** * @param args */ pu

Java多线程-Lock的使用

ReentrantLock类 在JDK1.5中,新增了 ReentrantLock,相比 synchronized 在扩展功能上更加强大,比如具有嗅探锁定.多路分支通知等功能. 示例: public class Test { public static void main(String[] args) { MyService service = new MyService(); new Thread(() -> service.methodA()).start(); new Thread(()

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

在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(ReentrantLock)以及读写锁(ReentrantReadWriteLock). 1. ReentrantLock 在Java多线程(二) 多线程的锁机制 里面,已经总结过通过使用Synchronized关键字实现线程内的方法锁定.但使用Synchronized关键字有一些局限性,上锁和释放锁是由JVM决定的

Java多线程学习篇(三)Lock

Lock 是Java多线程的一个同步机制,用来控制线程对共享资源的访问.线程在执行同步方法或者代码块之前必须先获得一个锁. Lock 的 lock() 和 unlock() 方法; lock():获得一个锁,如果锁不可用,则当前线程将因线程调度目的而被禁用,并在获得锁之前处于休眠状态. unlock():释放掉获得的锁. Lock的作用范围: 若 Lock 是静态的,则作用范围是整个类. public class Test { public static void main(String[] a

Java多线程编程中的lock使用源码详解

将做工程过程重要的代码段做个记录,如下的代码内容是关于Java多线程编程中的lock使用详解的代码,应该是对码农有帮助. import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.locks.Lock; import java.util.concurrent.l

“全栈2019”Java多线程第二十七章:Lock获取lock/释放unlock锁

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第二十七章:Lock获取lock/释放unlock锁 下一章 "全栈2019"Java多线程第二十八章:公平锁与非公平锁详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回

(转载)Java多线程入门理解

转载出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢?如果你觉得此文很简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 目录(?)[-] 一扩展javalangThread类 二实现javalan

Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为"独占锁". 顾名思义,ReentrantLock锁在同一个时间点只能被一个线程锁持有:而可重入的意思是,ReentrantLock锁,可以被单个线程多次获取.ReentrantLock分为"公平锁"和"非公平锁".它们的区别体现在获取锁的机制上是否公平."锁"是为了保护竞争资源,防止多个线程同时操作线程而出错,ReentrantLock在

synchronized与static synchronized 的差别、synchronized在JVM底层的实现原理及Java多线程锁理解

本Blog分为例如以下部分: 第一部分:synchronized与static synchronized 的差别 第二部分:JVM底层又是怎样实现synchronized的 第三部分:Java多线程锁,源码剖析 第一部分:synchronized与static synchronized的差别 1.synchronized与static synchronized 的差别 synchronized是对类的当前实例进行加锁,防止其它线程同一时候訪问该类的该实例的全部synchronized块.注意这里