避免在锁中使用阻塞操作

Java 9并发编程指南 目录

避免在锁中使用阻塞操作

阻塞操作是在事件发生之前,阻止当前线程执行。典型的阻塞操作是那些涉及控制台、文件或网络的输入或输出操作。

如果在锁临界区内部使用阻塞操作,则会使应用性能恶化。当一个线程等待将结束阻塞操作的事件时,应用的其它部分可能也在等待相同的事件。然而其余线程无法访问临界区且执行其代码(临界区的代码)。

本节将实现这种情况的范例,线程从临界区中的控制台读取行。这个指令将阻塞应用的其余线程,直到引入此行。

准备工作

本范例通过Eclipse开发工具实现。如果使用诸如NetBeans的开发工具,打开并创建一个新的Java项目。

实现过程

通过如下步骤实现范例:

  1. 创建名为Task的类,指定其实现Runnable接口:

    public class Task implements Runnable{
    
  2. 声明名为lock的私有Lock属性:

    	private final Lock lock;
    
  3. 实现类构造函数,初始化属性:

    	public Task (Lock lock) {
    		this.lock=lock;
    	}
    
  4. 实现run()方法:

    	@Override
    	public void run() {
    		System.out.printf("%s: Starting\n", Thread.currentThread().getName());
    
  5. 使用lock()方法获取锁:

    		lock.lock();
    
  6. 调用criticalSection()方法:

    		try {
    			criticalSection();
    
  7. 从控制台读取行:

    			System.out.printf("%s: Press a key to continue: \n", Thread.currentThread().getName());
    			InputStreamReader converter = new InputStreamReader(System.in);
    			BufferedReader in = new BufferedReader(converter);
    			String line=in.readLine();
    		} catch (IOException e) {
    			e.printStackTrace();
    
  8. 在finally部分中使用unlock()方法释放锁:

    		} finally {
    			lock.unlock();
    		}
    	}
    
  9. 实现criticalSection()方法,等待随机时间周期:

    	private void criticalSection() {
    		Random random=new Random();
    		int wait=random.nextInt(10);
    		System.out.printf("%s: Wait for %d seconds\n", Thread.currentThread().getName(),wait);
    		try {
    			TimeUnit.SECONDS.sleep(wait);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}	
    	}
    }
    
  10. 实现本范例主类,创建名为Main的类,包含main()方法:

    public class Main {
    	public static void main(String[] args) {
    
  11. 创建名为lock的新的ReentrantLock对象,创建10个Task对象和10个执行它们的线程:

    		ReentrantLock lock=new ReentrantLock();
    		for (int i=0; i<10; i++) {
    			Task task=new Task(lock);
    			Thread thread=new Thread(task);
    			thread.start();
    		}
    	}
    }
    

工作原理

当执行本范例时,10个线程开始执行,但只有一个进入在run()方法中实现的临界区。当每个任务在释放锁之前从控制台读取行时,所有应用都将被阻塞,直到在控制台中引入文本。

更多关注

  • 本章“保持锁的时间尽可能短”小节
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值