`
zhchx0827
  • 浏览: 191771 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

并发(三)

 
阅读更多

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的用法,为什么第一种可以正常的去尝试获取,获取不到锁时就继续执行,第二种还是会发生阻塞

分享到:
评论

相关推荐

    01-并发编程之深入理解JMM&并发三大特性(一).pdf

    并发编程之深入理解JMM&并发三大特性

    Java系统的高并发解决方法详解

    主要介绍了Java系统的高并发解决方法,内容十分丰富,在这里分享给大家,需要的朋友可以参考。

    Java并发三大性质.docx

    只有第1个语句是原子操作,将10赋值给线程工作内存的变量a,而语句2 a++,实际上包含了三个操作:读取变量a的值;对进行加1的操作,将计算后的值在赋值给变量a,而这三个操作都无法构成原子操作。对语句3,4的分析...

    阿里Java并发程序设计教程

    1、使用线程的经验:设置名称、响应中断、使用ThreadLocal 2、Executor :ExecutorService和...9、并发三大定律:Amdahl、Gustafson、Sun-Ni 10、神人和图书、相关网络资源 11、业界发展情况: GPGPU、OpenCL 12、复习题

    Java多线程并发编程 并发三大要素

    主要介绍了Java多线程并发编程 并发三大要素,需要的朋友可以参考下

    Java并发程序设计教程

    内容列表 1、使用线程的经验:设置名称、响应中断、使用ThreadLocal 2、Executor :ExecutorService和...9、并发三大定律:Amdahl、Gustafson、Sun-Ni 10、神人和图书 11、业界发展情况: GPGPU、OpenCL 12、复习题

    Java编程并发程序设计

    1、使用线程的经验:设置名称、响应中断、使用ThreadLocal 2、Executor :ExecutorService和Future ☆☆☆ ...9、并发三大定律:Amdahl、Gustafson、Sun-Ni 10、神人和图书 11、业界发展情况: GPGPU、OpenCL 12、复习题

    java高并发处理方法

    总共有6小节介绍解决方案,个人觉得是挺有用的

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段37讲 Phaser工具的实战案例使用第三部分_.mp4  高并发编程第三阶段38讲 Executor&amp;ExecutorService讲解_.mp4  高并发编程第三阶段39讲 ThreadPoolExecutor七大构造参数详细讲解_.mp4  高...

    聊聊并发系列文章

    3. 聊聊并发(三)Java线程池的分析和使用 4. 聊聊并发(四)深入分析ConcurrentHashMap 5. 聊聊并发(五)原子操作的实现原理 6. 聊聊并发(六)ConcurrentLinkedQueue的实现原理 7. 聊聊并发(七)Java中的阻塞...

    33.第三十三阶段、互联网企业高并发解决方案视频全集

    33.第三十三阶段、互联网企业高并发解决方案视频全集,33.第三十三阶段、互联网企业高并发解决方案视频全集,33.第三十三阶段、互联网企业高并发解决方案视频全集,33.第三十三阶段、互联网企业高并发解决方案视频...

    三份数据库并发处理方案

    数据库并发处理方案,数据库并发控制技术的研究等,其中 包括了3个文件,PDF格式,主要是讲数据库并发处理

    实验三 并发与调度2.doc

    计算机操作系统(第四版)实验3答案

    Java并发编程-3.pdf

    B站楠哥JUC Java并发编程

    Java 高并发三:Java内存模型和线程安全详解

    本文主要介绍Java高并发内存模型和线程安全的资料,这里整理详细的资料及1.原子性 2.有序性 3.可见性 4.Happen-Before 5.线程安全的概念,有需要的小伙伴可以参考下

    java并发基础.bmp

    java并发基础的大纲图,包含并发三大根源问题,各种并发问题,java内存模型如何解决,线程生命周期等

    实战Java高并发程序设计 中文pdf版下载

    第三,详细讨论有关“锁”的优化和提高并行程序性能级别的方法和思路。第四,介绍并行的基本设计模式及Java8对并行程序的支持和改进。第五,介绍高并发框架Akka的使用方法。最后,详细介绍并行程序的调试方法。 实战...

    C#编程高并发的几种处理方法详解

    并发(英文Concurrency),其实是一个很泛的概念,字面意思就是“同时做多件事”,不过方式有所不同。在.NET的世界里面,处理高并发大致有以下几种方法: 1、异步编程 异步编程就是使用future模式(又称promise)...

Global site tag (gtag.js) - Google Analytics