Java.util.concurrent need to know about the 5 things (1)

This Author: Ted Neward Address: http://www.ibm.com/developerworks/java/library/j-5things4.html

This concurrent programming guide for beginners (like me) = = through concurrent multi-threaded programming ~ Collections

Description: Write to good execution, preventing damage to the multi-threaded application code is very difficult task - this is the reason why we need java.util.concurrent. Ted Neward shows you will be concurrent to the Collections class, such as CopyOnWriteArrayList, BlockingQueue, there ConcurrentMap, how the demand for your concurrent program to improve the standard Collections classes.

Concurrent Collections is a Java ™ 5 great add-on products, but the dispute on the comments, and generic, many Java developers to ignore them. In addition (or, more honest to say), many developers avoid using the data packet, because they think it must be very complex, to solve the Wenti questions as it as.

In fact, java.util.concurrent contains many classes that can effectively solve the general problem of concurrency, without complicated procedures. Read this article to learn java.util.concurrent classes, such as CopyOnWriteArrayList and BlockingQueue can help you resolve the thorny issue of multi-threaded programming.

1. TimeUnit

Although not essentially Collections class, but make the code easier to read java.util.concurrent.TimeUnit enumeration. Use TimeUnit will use your method or API, developers from ms's "tyranny" liberate.

TimeUnit including all units of time, from MILLISECONDS and MICROSECONDS to DAYS and HOURS, which means that it can deal with a developer the necessary time frame for almost all types. At the same time, as listed on the statement in the conversion method, in time to speed up when converted back to MILLISECONDS HOURS even easier.

2. CopyOnWriteArrayList

Create a new copy of the array is too expensive, either from time or from the memory overhead, so rarely considered in their normal use; developers often resort to using synchronous ArrayList. However, this is a high cost of Xuanze because whenever you when iterating across the collection content, You have to synchronize all operations, including read and write, This ensure consistency.

This brings back the cost structure of a scene: many readers are required to read ArrayList, but few people would go to modify it.

CopyOnWriteArrayList is a smart little baby: roll:, to solve this problem. It's Javadoc will CopyOnWriteArrayList defined as a "ArrayList thread safe variant of this variant in all the variable operations (add, set, etc.) by copying the new array can be achieved."

Collection from within the content it does not modify the copy to a new array, so when the reader to access the contents of the array does not produce synchronization costs (since they never operate in the volatile data).

In essence, CopyOnWriteArrayList very suitable for handling ArrayList often we fail this scenario: read frequently, but few write a collection, such as JavaBean events Listener s.

(Copy on write memory model is also operating a very popular and classic strategy, similar to strategies such as Load on calling: to prevent the program from loading at startup cost, the typical type of single case of lazy mode but there is such a ~ when to Load on Startup, such as start of class depends on many other classes, or to ensure the availability of resources, so that when you call it when the error (= = Ali webx start on the first object loaded a pile of Service the ~)).

3. BlockingQueue

BlockingQueue interfaces that it is a Queue, meaning it's key to first in first out (FIFO) order of storage. Insert the key in a specific sequence in the same order of search - but requires additional assurance, retrieve an item from an empty queue will block any attempt to the calling thread until the item is ready to be retrieved. Similarly, you want to insert an item into the queue full of attempts to block the calling thread will result until the queue storage space is available.

BlockingQueue neat solution to a thread on how to collect the item "transfer" to another thread to handle the problem, regardless of synchronization. Java Tutorial's Guarded Blocks trial version is a good example. It is bound to build a single-slot buffer, when the new items available, and slots are also ready to accept a new item, use the manual synchronization and wait() / notifyAll() sent between threads.

Although Guarded Blocks tutorial code effective, but it took a long time, confusion, and are not completely intuitive. Back to the Java platform to an earlier time, yes, Java developers have to dwell on this code; but now it is 2010 - Can not improved the situation?

Listing 1 shows Guarded Blocks rewritten version of the code, which I use a ArrayBlockingQueue, rather than handwritten Drop.

import java.util.*;
import java.util.concurrent.*;

class Producer
    implements Runnable
{
    private BlockingQueue drop;
    List messages = Arrays.asList(
        "Mares eat oats",
        "Does eat oats",
        "Little lambs eat ivy",
        "Wouldn't you eat ivy too?");

    public Producer(BlockingQueue d) { this.drop = d; }

    public void run()
    {
        try
        {
            for (String s : messages)
                drop.put(s);
            drop.put("DONE");
        }
        catch (InterruptedException intEx)
        {
            System.out.println("Interrupted! " +
                "Last one out, turn out the lights!");
        }
    }
}

class Consumer
    implements Runnable
{
    private BlockingQueue drop;
    public Consumer(BlockingQueue d) { this.drop = d; }

    public void run()
    {
        try
        {
            String msg = null;
            while (!((msg = drop.take()).equals("DONE")))
                System.out.println(msg);
        }
        catch (InterruptedException intEx)
        {
            System.out.println("Interrupted! " +
                "Last one out, turn out the lights!");
        }
    }
}

public class ABQApp
{
    public static void main(String[] args)
    {
        BlockingQueue drop = new ArrayBlockingQueue(1, true);
        (new Thread(new Producer(drop))).start();
        (new Thread(new Consumer(drop))).start();
    }
}

ArrayBlockingQueue also reflects the "fair" - meaning it provides the reader and the writer thread FIFO access. This alternative method is a more effective, but to take the risk of exhausting the policy part of the thread. (That is, allowing some of the other reader reader lock to run more efficient, but you may have read the threads of the continuing flow of risk, leading to the preparation was unable to work.)

Note that Bug!

By the way, if you notice Guarded Blocks contains a major bug, then you are right - if developers main() the Drop instances simultaneously, what will happen?

BlockingQueue also supports the reception time parameter method, time parameters indicate that the thread is returned to signal failure to insert or retrieve information about the item before the need to block time. Doing so would avoid the non-binding wait, that is fatal to a production system, because a non-binding wait will be very easily lead to need to reboot the system hangs.

4. ConcurrentMap

Map a subtle concurrency bug, this bug will be many without the knowledge of Java developers astray. ConcurrentMap is the easiest solution.

When a Map visit was from multiple threads, usually containsKey() or get() to see whether the given key store key / value pairs appear before. But even if there is a synchronized Map, threads can still sneak in the process, and then seize control of the Map. The problem is the call on put() locked in get() the beginning of the acquisition, then you can get the lock again before the release. It is the result of competitive conditions: it is the competition between the two threads, the results will differ because of who should run.

If two threads call a method is almost the same time, both will be tested, call the put, the first thread in the treatment of missing values. Fortunately, ConcurrentMap interface supports many additional ways, they are designed for two tasks under a lock: putIfAbsent(), for example, the first test, and then only when the key is not stored in Map the time to put.

5. SynchronousQueues

According to Javadoc, SynchronousQueue is an interesting thing:

This is a blocking queue in which each insert operation must wait for another thread of the corresponding removal operation, and vice versa. A synchronous queue does not have any internal capacity, even with a capacity.

In essence, SynchronousQueue was mentioned earlier that the BlockingQueue another realization. It provides us with a single element in the exchange between threads very lightweight methods, the use of blocking ArrayBlockingQueue semantics. In Listing 2, I rewrite a code, use SynchronousQueue alternative ArrayBlockingQueue:

Listing 2. SynchronousQueue

import java.util.*;
import java.util.concurrent.*;

class Producer
    implements Runnable
{
    private BlockingQueue drop;
    List messages = Arrays.asList(
        "Mares eat oats",
        "Does eat oats",
        "Little lambs eat ivy",
        "Wouldn't you eat ivy too?");

    public Producer(BlockingQueue d) { this.drop = d; }

    public void run()
    {
        try
        {
            for (String s : messages)
                drop.put(s);
            drop.put("DONE");
        }
        catch (InterruptedException intEx)
        {
            System.out.println("Interrupted! " +
                "Last one out, turn out the lights!");
        }
    }
}

class Consumer
    implements Runnable
{
    private BlockingQueue drop;
    public Consumer(BlockingQueue d) { this.drop = d; }

    public void run()
    {
        try
        {
            String msg = null;
            while (!((msg = drop.take()).equals("DONE")))
                System.out.println(msg);
        }
        catch (InterruptedException intEx)
        {
            System.out.println("Interrupted! " +
                "Last one out, turn out the lights!");
        }
    }
}

public class SynQApp
{
    public static void main(String[] args)
    {
        BlockingQueue drop = new SynchronousQueue();
        (new Thread(new Producer(drop))).start();
        (new Thread(new Consumer(drop))).start();
    }
}

Implementation code looks almost the same, but the application has additional benefits: SynchronousQueue allow for an insert in the queue, as long as there is a thread waiting to use it.

In practice, SynchronousQueue similar languages such as Ada and CSP is available in the "join channel." These channels are sometimes called in other environments, "connection", this environment include. NET.

Conclusion: roll:

When the Java run-time knowledge base to facilitate concurrency preset time, why struggle trying to concurrency into your Collections class? Next article in this series will further explore the java.util.concurrent namespace content.

This article references:

分类:Java 时间:2010-08-10 人气:177
分享到:
blog comments powered by Disqus

相关文章

  • JAVA processing time - java.sql.Date.java.util.Date in the Date field in the database conversion method 2010-03-29

    1, how java.util.Date into a java.sql.Date? Transformation: java.sql.Date sd; java.util.Date ud; / / initialize the ud such as ud = new java.util.Date (); sd = new java.sql.Date (ud.getTime ()); 2, if you want to insert into the database and the corr

  • [Change] Java.util.date and java.sql.date difference and change 2010-08-02

    1, will be converted to java.sql.Date java.util.Date java.sql.Date sd; java.util.Date ud; / / Initialize the ud such as ud = new java.util.Date (); sd = new java.sql.Date (ud.getTime ()); 2, to insert into the database and the corresponding field for

  • Reprint: java.util.Date and java.sql.Date and transformation of the difference between 2010-08-05

    java.util.Date is the case in addition to the following SQL statement to use java.sql.Date is used for SQL statements, it only contains the date and time for some of it did not have the getTime method returns the number of milliseconds, naturally, ca

  • Java.util.date and java.sql.date difference and change 2010-09-19

    1, will be converted to java.sql.Date java.util.Date java.sql.Date sd; java.util.Date ud; / / Initialize the ud such as ud = new java.util.Date (); sd = new java.sql.Date (ud.getTime ()); 2, to insert into the database and the corresponding field for

  • java.util.Date and java.sql.Date system conversion and converted to a date time format string 2010-11-26

    1, will be converted to a java.sql.Date java.util.Date java.sql.Date sd; java.util.Date ud; / / Initialize the ud such as ud = new java.util.Date (); sd = new java.sql.Date (ud.getTime ()); 2, to insert into the database and the corresponding field f

  • Convert java.sql.Date to java.util.Date 2011-01-08

    [B] Method One: java.sql.Date sd; java.util.Date ud; / / Initialize the ud such as ud = new java.util.Date (); sd = new java.sql.Date (ud.getTime ()); Method Two: java.util.Date date = new java.util.Date (); / / 1. Set format java.text.SimpleDateForm

  • Oracle Date field operations (java.util.Date | java.sql.Date | java.sql.Timestamp)) 2011-02-16

    First show a little bit of time these common relationships between the classes A java.util.Date into a String java.util.Date udate=Calendar.getInstance().getTime(); Format f = new SimpleDateFormat("yyyy-MM-dd hh24:mm:ss"); System.out.println(f.f

  • 实用工具类库java.util 2012-03-09

    本章介绍Java的实用工具类库java.util包.在这个包中,Java提供了一些实用的方法和数据结构.例如,Java提供日期(Data)类.日历 (Calendar)类来产生和获取日期及时间,提供随机数(Random)类产生各种类型的随机数,还提供了堆栈(Stack).向量 (Vector) .位集合(Bitset)以及哈希表(Hashtable)等类来表示相应的数据结构. 图1.1给出了java.util包的基本层次结构图.下面我们将具体介绍其中几个重要的类. ┌java.util.BitS

  • java.util.Date.java.sql.Date.java.sql.Time.java... 2012-07-17

    转自: java.lang.Object ....|__java.util.Date ..........|__java.sql.Date/java.sql.Timestamp /java.sql.Time [父类]java.util.Date日期格式为:年月日时分秒 [子类]java.sql.Date日期格式为:年月日[只存储日期数据不存储时间数据] [子类]java.sql.Time日期格式为:时分秒 [子类]java.sql.Timestamp日期格式为:年月日时分秒纳秒(毫微秒) 针对不

  • java.util.logging.Logger使用详解 2013-03-12

    java.util.logging.Logger使用详解 一.创建Logger对象 要使用J2SE的日志功能,首先要取得java.util.logging.Logger实例,这可以通过Logger类的两个静态getLogger()方法来取得: static Logger getLogger(String name) 查找或创建一个logger. static Logger getLogger(String name, String resourceBundleName) 为指定子系统查找或创建一

iOS 开发

Android 开发

Python 开发

JAVA 开发

开发语言

PHP 开发

Ruby 开发

搜索

前端开发

数据库

开发工具

开放平台

Javascript 开发

.NET 开发

云计算

服务器

Copyright (C) codeweblog.com, All Rights Reserved.

CodeWeblog.com 版权所有 黔ICP备15002463号-1

processed in 0.618 (s). 10 q(s)