文档章节

Java并行程序基础(四)

1527
 1527
发布于 2017/03/23 22:48
字数 827
阅读 7
收藏 0
  • 重入锁的好搭档:Condition条件

Condition和wait(),notify()方法的作用大致相同。但是wait()和notify()方法是和synchronized关键字合作使用,而Condition是与重入锁相关联。

void await() throws InterruptedException;
void awaitUninterruptibly();
long awaitNanos(long nanosTimeout) throws InterruptedException;
boolean await(long time, TimeUnit unit) throws InterruptedException;
boolean awaitUntil(Date deadline) throws InterruptedException;
void signal();
void signalAll();

await() 方法会使当前线程等待,同时释放当前锁,当其他线程中使用signal()或signalAll()方法时,线程会重新获得锁并继续执行。或者当前线程被中断也能跳出等待。

awaitUninterruptibly()方法与await()方法基本相同,但是它并不会在等待过程中响应中断。

singal()方法用于唤醒一个在等待中的线程。

package com.thread.t02;

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

public class Test02 implements Runnable{

	public static ReentrantLock lock = new ReentrantLock();
	public static Condition condition = lock.newCondition();
	@Override
	public void run() {
		try {
			lock.lock();
			condition.await();
			System.out.println("Thread is going on");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			lock.unlock();
		}
	}
	public static void main(String[] args) throws InterruptedException {
		Test02 t1 = new Test02();
		Thread t2 = new Thread(t1);
		t2.start();
		Thread.sleep(2000);
		//一定要在signal()上加锁
		lock.lock();
		condition.signal();
		lock.unlock();
	}
}
  • 信号量(Semaphore)

信号量是对锁的扩展。无论是内部锁synchronized还是重入锁ReentrantLock,一次都只允许一个线程访问资源,而信号量却可以指定多个线程,同时访问某一个资源。

package com.thread.t02;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemapDemo implements Runnable{

	final Semaphore semp = new Semaphore(5);
	@Override
	public void run() {
		try {
			semp.acquire();//信号量申请
			Thread.sleep(2000);
			System.out.println(Thread.currentThread().getId()+":done");
			semp.release();//信号量释放
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		ExecutorService exec = Executors.newFixedThreadPool(20);
		final SemapDemo demo = new SemapDemo();
		for(int i=0;i<20;i++){
			exec.submit(demo);
		}
	}
}
  • ReadWriteLock读写锁
读写锁的访问约束情况
 
非阻塞 阻塞
阻塞 阻塞
package com.thread.t02;

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo {

	private static Lock lock = new ReentrantLock();
	private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	private static Lock readLock = readWriteLock.readLock();
	private static Lock writeLock = readWriteLock.writeLock();
	private int value;
	
	public Object handleRead(Lock lock) throws InterruptedException{
		
		try {
			lock.lock();
			Thread.sleep(1000);
			return value;
		} finally {
			lock.unlock();
		}
	}
	
	public void handleWrite(Lock lock,int index) throws InterruptedException{
		try {
			lock.lock();
			Thread.sleep(1000);
			value = index;
		} finally {
			lock.unlock();
		}
	}
	
	public static void main(String[] args) {
		final ReadWriteLockDemo demo = new ReadWriteLockDemo();
		Runnable readRunnable = new Runnable() {
			@Override
			public void run() {
				try {
					demo.handleRead(readLock);
					demo.handleRead(lock);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
		
		Runnable writeRunnale = new Runnable() {
			@Override
			public void run() {
				try {
					demo.handleWrite(writeLock, new Random().nextInt());
					demo.handleWrite(lock, new Random().nextInt());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
		
		for(int i=0;i<18;i++){
			new Thread(readRunnable).start();
		}
		for(int i=18;i<20;i++){
			new Thread(writeRunnale).start();
		}
	}
}
  • 倒计时器: CountDownLatch
package com.thread.t02;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchDemo implements Runnable{

	static final CountDownLatch end = new CountDownLatch(10);
	static final CountDownLatchDemo demo = new CountDownLatchDemo();
	@Override
	public void run() {
		try {
			Thread.sleep(new Random().nextInt(10)*1000);
			System.out.println("check complete");
			end.countDown();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws InterruptedException {
		ExecutorService exec = Executors.newFixedThreadPool(10);
		for(int i=0;i<10;i++){
			exec.submit(demo);
		}
		end.await();
		System.out.println("Fire");
		exec.shutdown();
	}
	
}
  • 线程阻塞工具 类: LockSupport

LockSupport是一个非常方便的阻塞工具类,它可以在线程内的任意位置让线程阻塞。和Thread.suspend()相比,它弥补了由于resume()在前发生,导致线程无法继续执行的情况。和Object.wait()相比,它不需要获得某个对象的锁,也不会抛出InterruptedException异常。

LockSupport的静态方法park()可以阻塞当前线程, 类似的还有parkNanos(),parkUnitl()等方法。

package com.thread.t02;

import java.util.concurrent.locks.LockSupport;

public class LockSupportDemo {

	public static Object u = new Object();
	static ChangeObjectThread t1 = new ChangeObjectThread("t1");
	static ChangeObjectThread t2 = new ChangeObjectThread("t2");
	public static class ChangeObjectThread extends Thread{
		
		public ChangeObjectThread(String name){
			super.setName(name);
		}
		
		@Override
		public void run() {
		
			synchronized (u) {
				System.out.println("in "+getName());
				LockSupport.park();
			}
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		t1.start();
		Thread.sleep(1000);
		t2.start();
		LockSupport.unpark(t1);
		LockSupport.unpark(t2);
		t1.join();
		t2.join();
		
	}
}

 

© 著作权归作者所有

1527

1527

粉丝 9
博文 113
码字总数 45785
作品 0
成都
程序员
私信 提问
Java 与 F# 的并行程序处理对比

Azul System的Cliff Click博士是多核心JVM系统方面的专家,之前发表了一篇博文,首先比较了Java与C语言和C++的性能表现,但同时也讨论了C#和.NET。以下三个Cliffs博士的评论让人十分感兴趣:...

彭博
2012/03/09
3.4K
35
OSC 第 101 期高手问答 —— Java 高并发程序设计

OSCHINA 本期高手问答(12月02日- 12月08日)我们请来了《实战Java高并发程序设计》的作者 @葛一鸣 为大家解答关于 Java 的并行程序设计基础、思路、方法和实战 方面的问题。如: 现在的服务...

叶秀兰
2015/12/01
13K
84
你所需要的java提升篇大总结

java基础篇深入解析大总结 java基础(一) 深入解析基本类型 java基础(二) 自增自减与贪心规则 java基础(三) 加强型for循环与Iterator java基础(四) java运算顺序的深入解析 java基础(五) Str...

sihailoveyan
2018/04/25
0
0
Java培训实战教程之Java基础知识精华部分(四)(五)

Java培训实战教程之Java基础知识精华部分(四)_设计模式 =============================================================================Java培训实战教程之Java基础知识精华部分(四)_设计模...

黑泽明军
2018/04/13
0
0
Java程序员从笨鸟到菜鸟全部博客目录【2012年十一月七日更新】

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188 大学上了一年半,接触java也一年半了,虽然中间也有其他东西的学习,但是还是以java为主路线,想想这一年半,...

长平狐
2012/11/12
222
0

没有更多内容

加载失败,请刷新页面

加载更多

mysql-connector-java升级到8.0后保存时间到数据库出现了时差

在一个新项目中用到了新版的mysql jdbc 驱动 <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.18</version> ......

ValSong
今天
5
0
Spring Boot 如何部署到 Linux 中的服务

打包完成后的 Spring Boot 程序如何部署到 Linux 上的服务? 你可以参考官方的有关部署 Spring Boot 为 Linux 服务的文档。 文档链接如下: https://docs.ossez.com/spring-boot-docs/docs/r...

honeymoose
今天
6
0
Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
今天
8
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
5
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部