1:共享临界资源
非线程安全
public class EvenGenerator extends IntGenerator{
private int currentEvenValue = 0;
public int next() {
currentEvenValue++;
currentEvenValue++;
return currentEvenValue;
}
public static void main(String[] args) {
EvenChecker.test(new EvenGenerator(), 10);
}
}
class EvenChecker implements Runnable {
private IntGenerator generator;
public EvenChecker(IntGenerator generator,int ident) {
this.generator = generator;
}
public void run() {
while(!generator.isCancled()) {
int val = generator.next();
if(val%2!=0){
System.out.println(val + " not even!");
generator.cancled();
}
}
}
public static void test(IntGenerator generator,int count) {
ExecutorService exe = Executors.newCachedThreadPool();
for(int i=0;i<count;i++) {
//抢占临街资源:generator
exe.execute(new EvenChecker(generator, count));
}
exe.shutdown();
}
}
abstract class IntGenerator {
private volatile boolean cancled = false;
public abstract int next();
public void cancled() {
cancled = true;
}
public boolean isCancled() {
return cancled;
}
}
输出结果(具体输出几行不确定):
427 not even!
431 not even!
429 not even!
2:线程安全
1:基本上所有的并发模式在解决线程冲突问题的时候,都是采用序列化访问共享资源的方案(加锁后,一次只能有一个线程访问)。
2:所有对象自动含有单一的锁(也称为监视器)。在对象上调用任意synchronized方法时,对象都被加锁(其他的加锁方法也不能被其他线程访问,非线程安全的方法可以)
3:如果在类中有超过一个方法在处理临界资源,那么必须同步所有相关的方法。
synchronized
使用synchronized进行加锁
public synchronized int next() {
currentEvenValue++;
currentEvenValue++;
return currentEvenValue;
}
//可以在类的范围内防止对static数据的并发访问
public synchronized static void add() {
}
Lock
private Lock lock = new ReentrantLock();
public int next() {
lock.lock();
try {
currentEvenValue++;
currentEvenValue++;
lock.unlock();
return currentEvenValue;
} finally {
lock.unlock();
}
}
unlock()方法必须放置在finally语句中。return语句必须在try子句中出现,确保unlock()不会过早的发生,从而将数据暴露给第二个任务。
使用synchronized关键字时,需要的代码量少,出错的可能性小,解决特殊问题才用lock对象
synchronized不能尝试获取锁且最终失败,或者尝试一段时间后放弃
public class AttemptLocking {
private ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
final AttemptLocking al = new AttemptLocking();
new Thread() {
{
setDaemon(true);
}
public void run(){
al.lock.lock();
System.out.println("acquired");
}
}.start();
// Thread.yield();
TimeUnit.SECONDS.sleep(1);
al.untimed();
al.timed();
}
public void untimed() {
boolean captured = lock.tryLock();
try {
System.out.println("tryLock(): "+captured);
}finally {
if(captured) {
lock.unlock();
}
}
}
public void timed() {
boolean captured = false;
try {
captured = lock.tryLock(2, TimeUnit.SECONDS);
}catch (Exception e) {
throw new RuntimeException();
}
try {
System.out.println("tryLock(2,TimeUnit.seconds): " + captured);
} finally {
if(captured) {
lock.unlock();
}
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
Box w = new Box();
w.put();
w.remove();
}
}
class Box {
private int i=0;
private ReentrantLock lock = new ReentrantLock();
public void put() throws InterruptedException {
boolean flag = lock.tryLock();
System.out.println(flag);
if(flag) {
try {
i++;
System.out.println("increment:"+i);
TimeUnit.SECONDS.sleep(15);
} finally {
lock.unlock();
}
}else {
System.out.println("increment 锁不可用");
}
}
public void remove() throws InterruptedException {
boolean flag = lock.tryLock();
System.out.println(flag);
if(flag) {
try {
i--;
System.out.println("decreat:"+i);
TimeUnit.SECONDS.sleep(15);
} finally {
lock.unlock();
}
} else {
System.out.println("decreat 锁不可用");
}
}
}
还是没看明白trylock的用法,为什么第一种可以正常的去尝试获取,获取不到锁时就继续执行,第二种还是会发生阻塞
分享到:
相关推荐
并发编程之深入理解JMM&并发三大特性
三、数据库集群和库表散列 大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群或者库表...
只有第1个语句是原子操作,将10赋值给线程工作内存的变量a,而语句2 a++,实际上包含了三个操作:读取变量a的值;对进行加1的操作,将计算后的值在赋值给变量a,而这三个操作都无法构成原子操作。对语句3,4的分析...
Java多线程并发编程并发三大要素 Java多线程并发编程中,存在三个至关重要的要素:原子性、可见性和有序性。这三个要素是Java多线程并发编程的基础,是确保多线程程序的正确性和可靠性的关键。 一、原子性 原子性...
1、使用线程的经验:设置名称、响应中断、使用ThreadLocal 2、Executor :ExecutorService和...9、并发三大定律:Amdahl、Gustafson、Sun-Ni 10、神人和图书、相关网络资源 11、业界发展情况: GPGPU、OpenCL 12、复习题
内容列表 1、使用线程的经验:设置名称、响应中断、使用ThreadLocal 2、Executor :ExecutorService和...9、并发三大定律:Amdahl、Gustafson、Sun-Ni 10、神人和图书 11、业界发展情况: GPGPU、OpenCL 12、复习题
1、使用线程的经验:设置名称、响应中断、使用ThreadLocal 2、Executor :ExecutorService和Future ☆☆☆ ...9、并发三大定律:Amdahl、Gustafson、Sun-Ni 10、神人和图书 11、业界发展情况: GPGPU、OpenCL 12、复习题
总共有6小节介绍解决方案,个人觉得是挺有用的
实验三 并发与调度 本实验主要介绍了Windows操作系统中的并发和调度机制,包括核心应用服务、线程同步和线程间通讯等概念。其中,线程同步对象是协调线程和进程工作的关键,包括互锁数据、临界段、事件、互斥体和...
高并发编程第三阶段37讲 Phaser工具的实战案例使用第三部分_.mp4 高并发编程第三阶段38讲 Executor&ExecutorService讲解_.mp4 高并发编程第三阶段39讲 ThreadPoolExecutor七大构造参数详细讲解_.mp4 高...
步骤三:调整 machine.config 中的 processModel Machine.config 是 .NET Framework 的配置文件,用于设置 .NET 应用程序的行为。需要将 processModel 的 requestQueueLimit 设置到 100000。可以通过输入以下命令来...
高并发编程第三阶段37讲 Phaser工具的实战案例使用第三部分_.mp4 高并发编程第三阶段38讲 Executor&ExecutorService讲解_.mp4 高并发编程第三阶段39讲 ThreadPoolExecutor七大构造参数详细讲解_.mp4 高...
3. 聊聊并发(三)Java线程池的分析和使用 4. 聊聊并发(四)深入分析ConcurrentHashMap 5. 聊聊并发(五)原子操作的实现原理 6. 聊聊并发(六)ConcurrentLinkedQueue的实现原理 7. 聊聊并发(七)Java中的阻塞...
Java并发编程中的多线程协作机制 在 Java 并发编程中,多线程协作机制是非常重要的一部分。多线程协作机制是指在多线程编程中,多个线程之间如何协作、同步和通信,以达到共同完成某个任务的目的。Java 提供了多种...
33.第三十三阶段、互联网企业高并发解决方案视频全集,33.第三十三阶段、互联网企业高并发解决方案视频全集,33.第三十三阶段、互联网企业高并发解决方案视频全集,33.第三十三阶段、互联网企业高并发解决方案视频...
Java内存模型(Java Memory Model,JMM)是Java多线程编程中一个至关重要的概念,它定义了共享变量在多线程环境下的行为规则,主要包括原子性、有序性和可见性三大特性。 1. 原子性 原子性是指一个操作是不可中断的...
数据库并发处理方案,数据库并发控制技术的研究等,其中 包括了3个文件,PDF格式,主要是讲数据库并发处理
本文将提供三种改造方案来解决Impala并发查询缓慢问题,并对每种方案进行测试验证和比较。 解决方案一:将 TIMESTAMP 改为 STRING 类型 在Impala并发查询缓慢问题中,TIMESTAMP 字段类型是导致性能下降的主要原因...
三、Semaphore Semaphore 是一种计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的...