Concurrent Random Numbers

In JDK 7, java.util.concurrent includes a convenience class, ThreadLocalRandom, for applications that expect to use random numbers from multiple threads or ForkJoinTasks.

For concurrent access, using ThreadLocalRandom instead of Math.random() results in less contention and, ultimately, better performance.

All you need to do is call ThreadLocalRandom.current(), then call one of its methods to retrieve a random number. Here is one example:

int r = ThreadLocalRandom.current() .nextInt(4, 77);

译文:
  在JDK 7中,java.util.concurrent包括了一个便利的类,ThreadLocalRandom,对于应用程序希望用随机数在多线程中或者ForkJoinTasks.
  对于并发使用,利用ThreadLocalRandom代替Math.Random()导致一些争议,基本上,性能上更好。
  所有你要做的是调用ThreadLocalRandom.current(),然后调用它的方法重新获得一个随机数。这是一个实例:
  int r = ThreadLocalRandom.current() .nextInt(4, 77);


For Further Reading

  • Concurrent Programming in Java: Design Principles and Pattern (2nd Edition) by Doug Lea. A comprehensive work by a leading expert, who's also the architect of the Java platform's concurrency framework.
  • Java Concurrency in Practice by Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, and Doug Lea. A practical guide designed to be accessible to the novice.
  • Effective Java Programming Language Guide (2nd Edition) by Joshua Bloch. Though this is a general programming guide, its chapter on threads contains essential "best practices" for concurrent programming.
  • Concurrency: State Models & Java Programs (2nd Edition), by Jeff Magee and Jeff Kramer. An introduction to concurrent programming through a combination of modeling and practical examples.
  • Java Concurrent Animated: Animations that show usage of concurrency features.
 

译文:
进一步阅读

  • Doug Lea的《Java的并发编程:设计原则和模式》(第二版)。一个领先的专家做了一些全面的工作。也是Java并发平台的架构师。
  • Brian Goetz,Tim Peierls,Joshua Bloch,Joseph Bowbeer,David Holmes,和Doug Lea的《Java 并发实例》。
  • Joshua Bloch的《高效的Java语言编程指南》(第二版),它关于线程的章节包含基本的并发编程的“最好实例”
  • Jeff Magee和Jeff Kramer的《并发:状态模型与Java程序》(第二版),一个通过实例和模型来介绍并发程序的书。
  • 《Java 并发动画》:展示并发特性的动画。

Questions and Exercises: Concurrency

Questions

  1. Can you pass a Thread object to Executor.execute? Would such an invocation make sense?

Exercises

  1. Compile and run BadThreads.java:

    public class BadThreads {
    
        static String message;
    
        private static class CorrectorThread
    extends Thread { public void run() {
    try {
    sleep(1000);
    } catch (InterruptedException e) {}
    // Key statement 1:
    message = "Mares do eat oats.";
    }
    } public static void main(String args[])
    throws InterruptedException { (new CorrectorThread()).start();
    message = "Mares do not eat oats.";
    Thread.sleep(2000);
    // Key statement 2:
    System.out.println(message);
    }
    }

    The application should print out "Mares do eat oats." Is it guaranteed to always do this? If not, why not? Would it help to change the parameters of the two invocations of Sleep? How would you guarantee that all changes to messagewill be visible in the main thread?

  2. Modify the producer-consumer example in Guarded Blocks to use a standard library class instead of the Drop class.

Check your answers.


译文:
问题和练习:并发
问题:
  1.你能用一个线程对象来执行Executor.execute吗?这样调用有意义吗?
练习:
  1.编译和运行BadThreads.java:

 public class BadThreads {

     static String message;

     private static class CorrectorThread
extends Thread { public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {}
// Key statement 1:
message = "Mares do eat oats.";
}
} public static void main(String args[])
throws InterruptedException { (new CorrectorThread()).start();
message = "Mares do not eat oats.";
Thread.sleep(2000);
// Key statement 2:
System.out.println(message);
}
}

  这个程序应该打印出"Mares do eat oats."它是否保证一直这样做?如果不,为什么?它是否会改变这个睡眠参数?你会如何保证在主程序中所有的message都是可见的?
  2.修改 Guarded Blocks节中生产者-消费者程序利用标准的类库程序代替Drop类。


Answers to Questions and Exercises: Concurrency

Questions

  1. Question: Can you pass a Thread object to Executor.execute? Would such an invocation make sense? Why or why not?

    Answer: Thread implements the Runnable interface, so you can pass an instance of Thread to Executor.execute. However it doesn't make sense to useThread objects this way. If the object is directly instantiated from Thread, its run method doesn't do anything. You can define a subclass ofThread with a useful run method — but such a class would implement features that the executor would not use.

Exercises

  1. Exercise: Compile and run BadThreads.java:

    public class BadThreads {
    
        static String message;
    
        private static class CorrectorThread
    extends Thread { public void run() {
    try {
    sleep(1000);
    } catch (InterruptedException e) {}
    // Key statement 1:
    message = "Mares do eat oats.";
    }
    } public static void main(String args[])
    throws InterruptedException { (new CorrectorThread()).start();
    message = "Mares do not eat oats.";
    Thread.sleep(2000);
    // Key statement 2:
    System.out.println(message);
    }
    }

    The application should print out "Mares do eat oats." Is it guaranteed to always do this? If not, why not? Would it help to change the parameters of the two invocations of Sleep? How would you guarantee that all changes to message will be visible to the main thread?

    Solution: The program will almost always print out "Mares do eat oats." However, this result is not guaranteed, because there is no happens-before relationship between "Key statement 1" and "Key statment 2". This is true even if "Key statement 1" actually executes before "Key statement 2" — remember, a happens-before relationship is about visibility, not sequence.

    There are two ways you can guarantee that all changes to message will be visible to the main thread:

    • In the main thread, retain a reference to the CorrectorThread instance. Then invoke join on that instance before referring to message
    • Encapsulate message in an object with synchronized methods. Never reference message except through those methods.

    Both of these techniques establish the necessary happens-before relationship, making changes to message visible.

    A third technique is to simply declare message as volatile. This guarantees that any write to message (as in "Key statement 1") will have a happens-before relationship with any subsequent reads of message (as in "Key statement 2"). But it does not guarantee that "Key statement 1" willliterally happen before "Key statement 2". They will probably happen in sequence, but because of scheduling uncertainities and the unknown granularity of sleep, this is not guaranteed.

    Changing the arguments of the two sleep invocations does not help either, since this does nothing to guarantee a happens-before relationship.

  2. Exercise: Modify the producer-consumer example in Guarded Blocks to use a standard library class instead of the Drop class.

    Solution: The java.util.concurrent.BlockingQueue interface defines a get method that blocks if the queue is empty, and a put methods that blocks if the queue is full. These are effectively the same operations defined by Drop — except that Drop is not a queue! However, there's another way of looking at Drop: it's a queue with a capacity of zero. Since there's no room in the queue for any elements, every get blocks until the corresponding take and every take blocks until the corresponding get. There is an implementation of BlockingQueue with precisely this behavior:java.util.concurrent.SynchronousQueue.

    BlockingQueue is almost a drop-in replacement for Drop. The main problem in Producer is that with BlockingQueue, the put and get methods throwInterruptedException. This means that the existing try must be moved up a level:

    import java.util.Random;
    import java.util.concurrent.BlockingQueue; public class Producer implements Runnable {
    private BlockingQueue<String> drop; public Producer(BlockingQueue<String> drop) {
    this.drop = drop;
    } public void run() {
    String importantInfo[] = {
    "Mares eat oats",
    "Does eat oats",
    "Little lambs eat ivy",
    "A kid will eat ivy too"
    };
    Random random = new Random(); try {
    for (int i = 0;
    i < importantInfo.length;
    i++) {
    drop.put(importantInfo[i]);
    Thread.sleep(random.nextInt(5000));
    }
    drop.put("DONE");
    } catch (InterruptedException e) {}
    }
    }

    Similar changes are required for Consumer:

    import java.util.Random;
    import java.util.concurrent.BlockingQueue; public class Consumer implements Runnable {
    private BlockingQueue<String> drop; public Consumer(BlockingQueue<String> drop) {
    this.drop = drop;
    } public void run() {
    Random random = new Random();
    try {
    for (String message = drop.take();
    ! message.equals("DONE");
    message = drop.take()) {
    System.out.format("MESSAGE RECEIVED: %s%n",
    message);
    Thread.sleep(random.nextInt(5000));
    }
    } catch (InterruptedException e) {}
    }
    }

    For ProducerConsumerExample, we simply change the declaration for the drop object:

    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.SynchronousQueue; public class ProducerConsumerExample {
    public static void main(String[] args) {
    BlockingQueue<String> drop =
    new SynchronousQueue<String> ();
    (new Thread(new Producer(drop))).start();
    (new Thread(new Consumer(drop))).start();
    }
    }
    answer 就不翻了


^_^本系列终于翻译完结了^_^撒花^_^高兴^_^
 
下一个系列要写啥了,有没有建议的啊?
 
 
 

【翻译二十三】java-并发程序之随机数和参考资料与问题(本系列完)的更多相关文章

  1. 二十三、并发编程之深入解析Condition源码

    二十三.并发编程之深入解析Condition源码   一.Condition简介 1.Object的wait和notify/notifyAll方法与Condition区别 任何一个java对象都继承于 ...

  2. 猫头鹰的深夜翻译:核心JAVA并发一

    简介 从创建以来,JAVA就支持核心的并发概念如线程和锁.这篇文章会帮助从事多线程编程的JAVA开发人员理解核心的并发概念以及如何使用它们. (博主将在其中加上自己的理解以及自己想出的例子作为补充) ...

  3. 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理

    二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ...

  4. 20155301第十二周java课程程序

    20155301第十二周java课程程序 内容一:在IDEA中以TDD的方式对String类和Arrays类进行学习 测试相关方法的正常,错误和边界情况 String类 charAt split Ar ...

  5. java并发程序和共享对象实用策略

    java并发程序和共享对象实用策略 在并发程序中使用和共享对象时,可以使用一些实用的策略,包括: 线程封闭 只读共享.共享的只读对象可以由多个线程并发访问,但任何线程都不能修改它.共享的只读对象包括不 ...

  6. Java并发程序设计(二)Java并行程序基础

    Java并行程序基础 一.线程的生命周期 其中blocked和waiting的区别: 作者:赵老师链接:https://www.zhihu.com/question/27654579/answer/1 ...

  7. Java 并发系列之二:java 并发机制的底层实现原理

    1. 处理器实现原子操作 2. volatile /** 补充: 主要作用:内存可见性,是变量在多个线程中可见,修饰变量,解决一写多读的问题. 轻量级的synchronized,不会造成阻塞.性能比s ...

  8. java并发程序——并发容器

    概述 java cocurrent包提供了很多并发容器,在提供并发控制的前提下,通过优化,提升性能.本文主要讨论常见的并发容器的实现机制和绝妙之处,但并不会对所有实现细节面面俱到. 为什么JUC需要提 ...

  9. 转:【Java并发编程】之二十三:并发新特性—信号量Semaphore(含代码)

    载请注明出处:http://blog.csdn.net/ns_code/article/details/17524153 在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作 ...

随机推荐

  1. OpenCV图像轮廓检测

    轮廓检测: 轮廓检测的原理通俗的说就是掏空内部点,比如原图中有3*3的矩形点.那么就可以将中间的那一点去掉. 一.关键函数1.1  cvFindContours函数功能:对图像进行轮廓检测,这个函数将 ...

  2. HDU 2860 并查集

    http://acm.hdu.edu.cn/showproblem.php?pid=2860 n个旅,k个兵,m条指令 AP 让战斗力为x的加入y旅 MG x旅y旅合并为x旅 GT 报告x旅的战斗力 ...

  3. 2016 Multi-university training contest

    day 1 A 给G,w(e)1M(diff),|V|100K,|E|1M,求 MST MST上任意两点间距离的期望 显然MST唯一 E(dis(u,v))可以通过计算每条边的贡献加出来 B n个并行 ...

  4. Oracle: SQL组合不同字段作为一个查询条件

    前端程序传过来的值是有三个字段组合之后的结果,后端程序处理,并且将查询的数据反馈给前端. PS:不能直接使用字段RPT_NO的,因为在这条记录中RPT_NO恰好等于其他三个字段的组合值. 正确的做法是 ...

  5. STL 阅读(浅析)

    写的不错,决定那这个看下.看的还是晕. http://luohongcheng.github.io/archives/

  6. javascript中apply、call和bind的区别,容量理解,值得转!

    a)  javascript中apply.call和bind的区别:http://www.cnblogs.com/cosiray/p/4512969.html b)  深入浅出 妙用Javascrip ...

  7. Unity Assets目录下的特殊文件夹名称

    1.隐藏文件夹以.开头的文件夹会被Unity忽略.在这种文件夹中的资源不会被导入,脚本不会被编译.也不会出现在Project视图中.2.Standard Assets在这个文件夹中的脚本最先被编译.这 ...

  8. iOS gcd dispatch使用注意,dispatch_syn可能产生的死锁

      我们在使用dispatch_sync 时可能会出现死锁,看下面的例子: import UIKit class ViewController: UIViewController { var seri ...

  9. iOS UILocalNotification 每2周,每两个月提醒

    iOS 的UILocalNotification提醒提供了默认的重复频率,比如,一天,一个星期等等,但是对于非标准的频率,比如每,2周,每2个月,无法重复提醒. 我们的思路是在应用程序开始时,把即将发 ...

  10. Metro各种流转换

    Ibuffer转byte[] ,(int)buffer.Length); Byte[]转Ibuffer WindowsRuntimeBufferExtensions.AsBuffer(bytes,,b ...