7. the Real-Time Clock API

Embed Size (px)

Citation preview

  • 8/10/2019 7. the Real-Time Clock API

    1/14

    The

    Reol-Tme

    ClockAPl

    "All

    my

    possessionsfor

    amoment

    of time."

    -Elizabeth

    I

    Tr

    chapter

    explores

    the

    implementation

    of

    the RTSJ

    def,nition

    of

    clocks

    and

    timers within

    Java

    RTS. The

    classes

    explored

    in

    detail

    provide

    jitter-free

    time

    operations,

    and

    access

    to a high-resolution

    clock for

    timer

    objects for

    different

    types

    of

    timers. For

    instance,

    you

    can

    create

    timer

    objects

    that

    cause

    time-related

    events to fire

    either

    periodically,

    or for

    one-time

    use.

    The

    ClockAPl

    Java RTS

    implements

    the RTSJ

    Clock

    API,

    which

    defines real-time

    clock

    and

    timer facilities. These

    classes

    should

    be used in

    place

    of

    calls

    to

    System.cur-

    rentTimeMilf

    is,

    System.nanoTime,

    and the

    java.util.Date

    class. They

    rep-

    resent

    points

    in time

    with the

    best

    possible

    accuracy

    and

    precision

    the

    underlying

    hardware

    can

    support,

    and

    distinguish

    between

    absolute

    points

    in time,

    and those

    relative

    to a starting

    point.

    Additionally,

    these classes

    allow

    the creation

    of timers

    that

    f,re

    either

    periodically,

    or

    for

    one

    time

    only, deterministically.

    Finally,

    the

    Java RTS

    implementation

    of these

    classes

    satisfles

    the

    POSIX

    real-time require-

    ment

    of

    providing

    access

    to

    high-resolution

    timers. For instance,

    the code in List-

    ingT-l

    checks

    and

    displays

    the

    resolution

    of

    the real-time

    clock

    the system

    it's

    executed on.

    223

  • 8/10/2019 7. the Real-Time Clock API

    2/14

    224

    Crupron

    7 Trun

    Rott-Tttp

    CtocxAPI

    Listing 7-1

    Output

    the RT

    clock

    accuracy

    i mport

    javax.

    real

    ti

    me.

    *;

    publ

    i

    c

    cl

    ass

    Mai n

    {

    public

    static

    void main(String[] args)

    {

    RelativeTime t

    -

    C'l

    ock.

    getRea'l

    timeCl

    ockO

    .

    getResol

    utionO

    ;

    System. out

    .

    pri

    ntl

    n

    (

    "Real-time

    clock

    resolution

    =

    "

    +

    t.toStringO);

    )

    ]

    Since

    timer

    resolution

    is

    hardware-dependent,

    you're

    likely to

    get

    different

    results

    on

    different

    systems

    you

    run

    Java

    RTS

    on.

    When

    the code

    in Listing

    7-1

    is

    exe-

    cuted on SunFire

    v240, the accuracy output

    is: a

    Real-time

    clock resolution =

    (0

    ms, 200 ns)

    Clearly,

    the timer resolution

    for

    Java

    RTS applications

    on

    this machine is 200

    nanoseconds. Keep in mind

    that the

    system

    you

    run

    Java

    RTS

    on

    must

    provide

    access to

    high-resolution timers, and the user

    account

    you

    execute

    your

    applica-

    tion

    with must

    have

    privilege

    to access

    the

    high-resolution timer implementation.

    To

    use

    the

    RTSJ

    Clock

    API

    (see

    Figure

    7-1)

    to

    create timestamps or

    high-

    resolution timings, begin by

    gaining

    a

    reference to the singleton real-time clock

    object

    via

    the

    getReal

    ti meCl

    ock

    O

    method call

    on

    the

    j

    avax

    .

    real

    ti me . Cl ock

    object,

    as

    seen

    in

    the

    previous example.

    To

    calculate

    a

    timestamp

    with

    nanosecond

    resolution

    (on

    hardware that

    supports it), use code similar to that

    in Listing

    7-2.

    Listing 7-2

    Real-time clock

    timestamp code

    javax.

    realtime.Clock

    rtClock

    =

    javax.

    realtime.Clock.

    getRealtimeClockO

    ;

    javax.

    realtime.Absol uteTime

    begi

    nTime

    ;

    j

    avax

    .

    real

    ti

    me .

    Absol

    uteTi

    me endTi me

    ;

    //

    get

    start

    time

    and

    convert

    to

    nanoseconds

    begi

    nTim

    =

    rtClock.

    getTimeO

    ;

    long lBegin

    =

    (beg'inTime.getMillisecondsO

    o

    1000000L) +

    rtt^/al I

    Cl

    ockTi meBefore

    .

    getNanoseconds

    O

    ;

    //

    do

    process'ing

    here..

    .

    //

    gel.

    end time

    and

    convert

    to

    nanoseconds

    endTift

    =

    rtClock.

    getTimeO

    ;

    long

    lEnd

    =

    (beginTime.getMillisecondsO

    o

    1000000L) +

    rtL\,al

    I Cl

    ockTi

    meBefore. getNanoseconds

    O

    ;

  • 8/10/2019 7. the Real-Time Clock API

    3/14

    Tttr

    CtocxAPI

    In

    addition

    to the

    high-resolution

    timing

    shown

    in Listing

    7-2, tluotgh

    a

    combination

    of

    the Clock

    and Absol

    uteTime

    classes,

    you

    can

    perform

    date

    and

    time

    operations.

    This includes gaining

    access

    to

    java.util.Date

    objects.

    The

    complete

    class

    diagram

    for

    the

    RTSJ

    time

    operations

    is

    shown inFigweT-2.

    javax.

    realtime.Clock

    +getEpochOffset0

    +getRealtimeClock0

    +getResolution0

    +getTime0

    +setResolution0

    Figure

    7-1.

    The

    Java

    RTS Clock

    class.

    i HignResolutionTime

    i

    r---------

    ------l

    i

    +absolute$

    i

    l

    ^r^-^/\

    I

    ;

    +ctoneQ

    ,

    i

    +compareTo$

    i

    i

    +equatsQ

    i

    i

    +gerCtockQ

    i

    i

    +getMittisecondsQ

    I

    I

    +getNanosecondsfl

    I

    ,

    l

    +hashCode

    I

    +relative0

    +set$

    +waitFor0bject0

    22

    +add0

    +getDate0

    +relative0

    +set$

    +subtractfl

    +tostring0

    +add0

    +relative0

    +subtract0

    +tostring0

    Figure

    7-2

    The

    Java

    RTS time

    operations.

  • 8/10/2019 7. the Real-Time Clock API

    4/14

    226

    CrutprnnT

    Tnr

    RmuTtun

    CrccxAPI

    +destroyO

    i

    +disableQ

    I

    +enableO

    i

    +fireO

    i

    +getClockQ

    i

    +getFireTime$

    i

    +handledBY$

    I

    I

    +

    isRunningQ

    ,

    +removeHanter1

    i

    +reschedulefl i

    +setHandleO

    i

    Figure 7-3 The Java RTS

    timer

    operations.

    We'll take

    a look at how to use these classes

    shortly.

    As

    mentioned earlier,

    the

    Cl ock

    API

    provides

    access

    to timers that can be set to

    expire

    periodically,

    or one

    time only.

    These

    classes

    are

    Peri odi

    cTi

    mer and OneShotTi mer, respectively

    (see

    Figure 7-3).

    Since

    these classes

    extend

    AsynchEvent,

    we'11

    examine

    these classes

    in

    detail

    in

    Chapter 8.

    Jovo

    RTS

    High-Resolution

    Time

    +getlnterval0

    +setlnterval0

    Operotions

    In

    Java

    RTS, real-time

    time

    objects

    are

    instances

    of

    either

    the

    Absol

    uteTi

    me

    or

    RelativeTime

    classes,

    and associated

    with

    a

    singleton real-time

    clock.

    In

    fact,

    we've already seen these

    classes used

    with

    setting

    the

    release

    parameters

    for

  • 8/10/2019 7. the Real-Time Clock API

    5/14

    J

    u, RTS

    H

    rcn-

    Resotuno,t

    Ttrun,

    O

    pnntnoN

    s

    periodic

    Real

    ti

    meTh

    read

    objects

    in

    Chapter

    5. However,

    there

    are

    more

    details

    to these classes

    that need

    to be

    examined.

    The Absol

    uteTi

    me

    class

    represents

    a

    specific

    point

    in

    time. It's

    specif,ed

    and

    measured

    in

    a combination

    of

    milliseconds

    and nanoseconds.

    Here

    are

    the

    Abso-

    I

    uteTi

    me

    class

    constructors:

    Absol

    uteTimeO---{reates

    a

    new

    object representing

    a time

    of 0

    milliseconds

    and nanoseconds.

    Absol

    uteTime(Absol

    uteTime)----creates

    a new

    object

    with

    the

    same

    starting

    time

    as

    the

    given

    object.

    Absol

    uteTime(Clock)-creates

    a new

    object

    associated

    with

    the

    given

    RTSJ

    Cl ock

    object.

    AbsouteTime(AbsoluteTime, Clock)-creates

    a new

    object

    with

    the same

    starting

    time

    as

    the

    given

    object,

    and associated

    with

    the

    given

    RTSJ

    Clock

    object.

    AbsoluteTime(Date)-creates

    a

    new

    object with

    a

    starting

    time of

    Date.

    getTi

    me.

    AbsoluteTime(Date,

    Clock)-creates

    a

    new

    object

    with

    a stafing

    time of

    Date.

    getTi

    me,

    and

    associated

    with

    the

    given

    RTSJ

    Cl

    ock

    object.

    Absol

    uteTi

    me

    (l

    ong

    mi

    1

    I

    i

    s

    ,

    i

    nt

    nanos)-creates

    a

    new object

    with

    a

    start-

    ing

    time represented

    by the

    given

    millisecond

    and nanosecond

    components.

    AbsoluteTime(long

    millis,

    int nanos,

    clock)---creates

    a new

    object

    with

    a starting

    time represented

    by

    the

    given

    millisecond

    and

    nanosecond

    com-

    ponents,

    and associated

    with

    the

    given

    RTSJ

    Cl

    ock object.

    The

    Rel

    ati

    veTi

    me

    class

    represents

    a time interval,

    such

    as

    a

    period

    of time rela-

    tive to the

    current

    time. It's frequently

    used

    when

    specifying

    a

    periodic

    real-time

    thread's

    period,

    a

    parameter

    to

    a Real

    ti

    meTh

    read

    .

    si

    eep

    call, or

    a

    call

    to

    a

    form

    of

    the wai

    t

    method

    when

    synchronizing

    on

    shared

    objects. The

    constructors

    for

    the Rel

    ati

    meTi me

    class are:

    RelativeTime(Iong

    mil

    I is,

    int

    nanos)-creates

    a

    new

    object

    that repre-

    sents

    the interval

    based on

    the

    provided

    milliseconds parameter,

    plus

    the

    pro-

    vided

    nanosecond parameter.

    In

    this case,

    the real-time

    clock

    is used

    by

    default.

    Re'lativeTime(long

    miI'lis,

    int

    nanos,

    clock)---creates

    a

    new

    object

    that represents

    the

    interval

    based

    on the

    provided

    milliseconds

    parameter,

    plus

    22

  • 8/10/2019 7. the Real-Time Clock API

    6/14

    228

    Cruprnn7

    Tnn

    Rnr-Ttur CrccxAPI

    the

    provided

    nanosecond

    parameter.

    In this

    case,

    the

    provided

    clock

    is

    used;

    if

    null,

    then the

    real-time

    clock

    is

    used by

    default.

    Re'lativeTimeO----creates

    a

    new object

    with zeros

    for both the

    milliseconds

    and

    nanoseconds

    parameter.

    The real-time

    clock

    is used by default.

    Rel

    ati

    veTi

    me

    (Cl

    ock)--creates

    a

    new object

    with

    zeros

    for

    both

    the

    millisec-

    onds and

    nanoseconds

    parameter.

    In this

    case,

    the

    provided

    clock

    is used; if

    null,

    then the

    real-time

    clock

    is

    used by

    default.

    Rel ativeTime(ReI

    ativeTime)-creates

    a

    new

    object

    from

    the one

    provided.

    RelativeTime(RelativeTime,

    Clock)----creates

    a

    new object

    from the one

    provided,

    using

    the

    clock

    provided.

    Both

    Hi

    ghResol

    uti

    onTi

    me

    classes

    allow

    you

    to

    perform

    time arithmetic,

    where

    you

    can add and subtract

    different

    time

    objects

    to

    derive new time

    objects.

    For

    instance, the code

    in Listing

    7-3

    is

    a

    very

    easy

    way

    to determine

    the amount of

    time a

    particular

    operation

    takes to execute.

    Listing 7-3

    Timing a

    real-time operation

    i mport

    j

    avax . real ti

    me.

    *

    ;

    public

    class

    Main

    {

    public

    static

    void

    main(String[]

    args)

    {

    //

    Create the objects

    beforehand; eliminates

    jitter

    AbsoluteTime

    before;

    AbsoluteTime after;

    RelativeTime elapsed;

    before

    =

    Clock.getReal

    timeClockO

    .getTimeO

    ;

    //

    perform

    operation

    here...

    after

    =

    Clock.getReal

    timeClockO

    .getTimeO

    ;

    elapsed

    =

    after.subtract(before)

    ;

    System.out.println("Elapsed

    time:

    "

    + elapsed)

    ;

    )

    ]

    As the comment at the

    beginning of the

    code

    says,

    we

    declare

    the time objects

    before the timed

    operation

    so

    that

    the

    object

    creating time doesn't

    get

    factored

    into

    the

    measurement. Since

    Cl

    ock

    operations

    are bounded and deterministic

    in

    Java

    RTS, the

    calls to

    getTi

    me are efflcient,

    and

    consistent, in terms of execution

    time.

    In

    fact, due to inherent

    jitter

    in the

    j

    ava. uti

    I

    .

    Date

    class,

    you

    should

    use Cl

    ock

    .

    getRealtimeClockO.getTime

    and

    the

    AbsoluteTime

    it

    returns

    for

    all

    time-

    stamping operations,

    such

    as

    that shown in

    Listing

    7-4.

  • 8/10/2019 7. the Real-Time Clock API

    7/14

    A

    Cotptrno

    SrocxDnt

    Fsr

    Ex*tptn

    Listing

    7-4

    Jitter-free

    Date code

    22

    AbsoluteTime

    current

    =

    clock.

    getRealtimeclockO

    .

    getTimeO

    ;

    Date

    tifi

    =

    current.getDateO;

    System.out.println("Current

    date/t'ime: "

    +

    time)

    ;

    Let's

    take

    a

    look

    at

    more

    involved example

    of

    how

    to

    use

    both

    the Absol

    uteTime

    and

    Rel

    ati veTi

    me

    classes.

    A

    Confloled

    Stock

    Doto

    Feed

    Exomple

    Let's

    examine

    a situation

    where

    we want

    to send

    conflated

    stock

    price

    data

    to

    cli-

    ent

    applications.

    The requirement

    is

    to

    gather

    all updates

    for

    a

    particular

    stock

    ticker

    as

    they occur in real-time, but

    send

    them no

    less

    than ten

    milliseconds

    apart.

    This

    means

    that for

    all

    updates

    that

    occur

    within each

    ten-millisecond

    period,

    the

    updates

    must

    be added

    together

    to form

    one

    overall

    update

    that is

    sent to

    the cli-

    ents

    (see

    Figure

    7-4). However,

    if

    more

    than

    ten milliseconds

    elapses

    between

    single

    updates,

    the

    update

    data

    gets

    transmitted

    immediately

    (there's

    no

    need

    to

    delay

    any

    longer).

    In

    the examples

    shown

    in

    this

    flgure,

    the

    stock

    price

    starts

    at a

    value

    of

    10.00.

    Before

    the

    first

    ten-millisecond

    conflation period

    (where

    an update

    to clients

    will

    be sent)

    four

    individual

    price

    updates

    are received

    from

    the

    external

    data

    feed

    for

    the

    stock

    being

    watched.

    Each

    price

    update

    is

    applied

    to

    the

    stock

    price,

    but

    the

    result

    is

    not

    sent until

    the conflation

    period

    expires.

    At that

    time,

    the stock

    price

    is

    9.48,

    which

    is

    the

    value

    sent

    in

    the

    update

    to the

    client

    applications.

    Stock

    start

    price:

    10.00

    Notify

    Clients

    Stock:

    9.37

    il

    Notify

    Clients

    Stock:9.48

    .'i'Il

    9.98

    9.48

    9.37

    0

    *--ro-r;poateliola-t.ro--'

    }0,

    *-----;upout-,,;------'

    i:

    One update

    (past

    conflation time)

    Figure

    7-4

    Conflated stock

    ticker

    updates.

  • 8/10/2019 7. the Real-Time Clock API

    8/14

    230

    Csprnn7 Tan Rp,r-TtusCtocxAPI

    However,

    during

    the

    next conflation

    period

    (another

    ten

    milliseconds)

    no

    price

    updates

    are

    received.

    Therefore,

    no conflated

    price

    update

    needs to

    be

    sent since

    the value

    hasn't changed.

    However,

    as

    soon

    as

    the

    next

    price

    update does

    occur,

    the

    resulting

    price

    will be sent

    out

    immediately

    (which

    is

    9.37

    in this example).

    At this

    point,

    the conflation

    timer

    is reset,

    and

    updates

    will

    be

    conflated

    for the

    next ten

    milliseconds.

    The description

    and

    diagram

    above

    lay the

    groundwork

    for

    our sample

    applica-

    tion.

    There's

    no need to

    create

    a

    periodic

    RTT;

    we'll

    simply

    use

    a

    starting

    time

    (an

    Absol uteTi

    me

    object)

    and

    wait on an

    object

    that will be signaled

    when

    an update

    occurs.

    However, we'Il

    use

    the

    H'i

    ghResol

    uti onTi me

    .

    wai

    tFo rObj

    ect

    method,

    which

    allows

    us to

    provide

    a

    maximum

    amount of

    time

    to

    wait. Therefore,

    with

    each

    update,

    the code

    will check

    the

    time

    elapsed,

    and if

    it's

    still

    within

    the

    confla-

    tion time

    period,

    the code

    will

    again

    wait

    but

    for

    the time

    remaining

    in the

    period.

    Implementing

    it

    this way allows

    us

    to demonstrate the

    use

    of

    Absol

    uteTi

    me

    and

    Rel ati

    veTi me objects,

    as

    well

    as Hi

    ghResol

    uti onTi

    me arithmetic

    in

    one

    mean-

    ingful

    example.

    In Chapter

    8,

    we'11

    modify

    this application

    to use

    a

    Ti mer

    object

    instead. For

    now,

    let's

    begin

    looking

    at Listing

    7-5.

    Listing 7-5

    The

    conflated

    stock

    update

    application

    i mport

    javax.

    real

    ti

    me.

    *;

    pubf

    ic

    class

    MyApp

    {

    Object

    lock

    =

    new

    ObjectO;

    double

    update

    =

    0.00;

    final

    RelativeTime

    PERI0D

    =

    nw

    RelativeTime(L0,0);

    //

    L0ms

    class Conflater

    extends

    RealtimeThread

    {

    boolean

    updateOccured

    =

    false;

    RelativeTime

    timeout

    =

    PERIOD;

    AbsoluteT'ime

    startTime

    =

    null;

    double

    pri

    ce

    =

    0.00i

    public

    void runO

    {

    // ...

    )

    private

    vojd updatecl

    i

    ents(

    double

    newPrice,

    RelativeTime

    lastUpdate)

    //

    ...

    ]

    ]

    class

    DataFeed

    extends

    RealtimeThread

    {

    private

    Object

    privlock

    =

    new

    ObjectO;

    pubf

    ic

    void

    runO

    {

  • 8/10/2019 7. the Real-Time Clock API

    9/14

    A

    Conrtrt

    SrocxDtr

    Fnto

    Exuptz,

    //

    ...

    ]

    private

    void

    send(int

    interval,

    double

    change)

    {

    //

    ...

    ]

    ]

    pub'lic

    MyAppO

    {

    Conflater

    conflater

    =

    w

    ConflaterO;

    DataFeed

    datafeed

    =

    hw

    DataFeedo;

    conflater.

    startO

    ;

    datafeed.

    startO

    ;

    ]

    public

    static

    void main(String[]

    args)

    {

    MYAPP

    PP

    =

    new

    MyAppO;

    ]

    From

    this

    code,

    you

    can

    see

    that

    there

    are

    two

    RealtimeThread

    classes:

    Con-

    flater,

    and

    DataFeed.

    The

    Conflater

    class

    object

    listens

    for

    updates

    from

    the

    DataFeed

    class object,

    and

    sends

    conflated

    updates

    to its

    clients

    at

    least

    every

    PERIOD

    amount

    of time. Both

    RTTs

    share

    the

    object 1ock,

    and each

    change

    to

    the

    stock is

    communicated

    through

    update.

    The

    Confloter

    Closs

    Let's

    take

    a

    look

    at

    class

    Conflater

    in

    more

    detail-see

    Listing

    7-6-as

    that's

    where

    the

    interesting

    code is.

    Listing

    7-6

    The

    Conflater

    class

    class

    Conflater

    extends

    RealtimeThread

    {

    boolean

    updateOccured

    =

    false;

    RelativeTime

    timeout

    =

    pERIOD;

    AbsoluteTime

    startTime

    =

    null;

    double

    pri

    ce

    =

    0.00i

    Clock rtClock

    =

    Clock.getRealtimeClockO

    ;

    public

    void

    runO

    {

    try

    {

    //

    Walt

    to

    receive

    start

    pr-ice,

    and

    begin

    conflation

    synchronized(lock){

    lock.waitO;

    ]

    Ltinued

    23

  • 8/10/2019 7. the Real-Time Clock API

    10/14

    232

    CrutprnnT

    Tae Rott-Tmr

    CucxAPI

    //

    Ihe first update

    is

    the

    starting

    price

    price

    =

    update;

    startTirx

    =

    FtClock.

    getTimeO

    ;

    System.

    out

    .

    pri

    ntl

    n

    (

    "Conflater received starting

    price")

    ;

    //

    Now

    wa'it

    for

    updates,

    apply

    them,

    and

    send

    //

    updated

    price

    to

    clients

    after conflated

    period

    while(true){

    synchroni

    zed

    (

    lock

    )

    {

    //

    wait

    for

    update

    or

    period

    to

    expire

    update

    =

    0.00

    Hi

    ghReso'l

    utionTime.waitForobject(l

    ock, timeout)

    ;

    AbsoluteTime

    current

    =

    rtClock.getTimeO;

    RelativeTime elapsed

    =

    cu

    r rent

    .

    subt

    ract

    (startTi

    me)

    ;

    //

    Check

    for update or timeout

    if

    (

    update

    =

    0.OO

    ) {

    //

    Apply

    update,

    and

    check time

    updateoccured

    =

    true;

    price

    += updti

    System.

    out .

    pri

    ntl n

    (

    "Conflater:

    update

    "

    + update +

    ",

    El

    apsed="

    +

    el

    apsed)

    ;

    timeout

    =

    PERIOD.subtract(

    elapsed

    );

    //

    First update

    since

    previous

    period

    if

    (

    elapsed.getMillisecondsO

    >

    PERIOD.

    getMi

    I

    I i secondsO

    )

    {

    //

    Send

    update,

    start

    new

    conflation

    period

    updateCl

    i

    ents(pri

    ce, e1 apsed)

    ;

    startTiffi

    =

    rtClock.

    getTimeO

    ;

    ]

    ]

    else

    {

    /

    /

    Conflati

    on

    period

    expi red

    if

    (

    updateOccured

    )

    t

    //

    Send

    update, start

    new conflation

    period

    updateCl

    i ents(pri

    ce, e1 apsed)

    ;

    startTifi

    =

    FtClock.

    getT'imeo

    ;

    ]

    ]

  • 8/10/2019 7. the Real-Time Clock API

    11/14

    A

    C

    o,t

    p

    trno

    Srocx Dm

    F nno

    E xrup

    to

    ]

    catch(Exceptione){

    e

    .

    pri

    ntstackTrace

    O ;

    )

    ]

    private

    void

    updateclients(

    double newprice,

    RelativeTime

    lastUpdate)

    {

    System.out.println("Conflater:

    Updating

    clients:

    ")

    ;

    System.out.print1n("Conflater:

    price="

    + newprice);

    System.out.println("Conflater:

    Time

    since last:,'

    +

    1 astUpdate)

    ;

    Send

    update

    //

    Reset

    some values

    timeout

    =

    PERIOD;

    updateOccured

    =

    false;

    The

    first

    update

    received

    is

    the

    starting price.

    From

    that

    point

    on, the

    thread

    enters

    an

    inf,nite

    loop

    waiting

    for an

    update,

    or

    the

    period

    to expire-whichever

    comes

    first.

    In

    the

    whi 1e

    loop,

    wai

    tForobject

    is called

    with

    a

    timeout

    value,

    which

    is

    initially

    set

    to

    the

    full ten-millisecond

    period.

    Therefore,

    one

    of

    two things

    can

    occur:

    an update

    arrives,

    which

    results

    in

    the

    wait

    call

    returning

    when

    the

    lock

    object

    is

    signaled,

    or the

    timeout period

    expires.

    When

    execution

    continues

    after

    wai

    tFor0bject,

    the

    elapsed

    time

    since

    the

    start

    of

    the

    conflation

    period

    is

    determined,

    and

    a check

    is

    made

    to

    see

    if

    a data feed

    update has

    arrived.

    This is

    simple-if

    the

    update

    price

    is

    non-zero,

    an update

    occurred.

    Otherwise

    the

    timeout

    value

    has

    expired.

    In

    the

    case

    of a

    price

    update,

    a

    flag

    is

    set

    (to

    be

    checked

    later, when the period expires),

    the

    price

    is

    adjusted

    accordingly,

    and the

    timeout

    value

    is

    set

    to the

    time remaining

    in

    the current

    period.

    However,

    if

    the

    elapsed

    time

    since the

    beginning

    of the

    period

    is

    greater

    than

    the

    period

    itself,

    then we

    know

    that

    a

    data

    feed

    update hasn't

    been received

    in

    the

    current

    period

    and this

    update

    needs

    to be

    sent to

    clients right

    away. The

    updateCl

    i

    ents

    method is

    called

    to

    perform

    this.

    In

    the

    case

    of

    a

    period

    timeout,

    a

    check is

    made

    to see if

    any

    data feed

    updates

    have

    occurred

    in

    the

    current

    period.

    If not,

    then

    nothing

    special is

    done,

    and

    the

    23

  • 8/10/2019 7. the Real-Time Clock API

    12/14

    234

    Cru*rr,n7

    Tnr

    Rn.r-Ttur

    CtocxAPI

    code

    again

    calls

    wai

    tFor0bject.

    If an

    update

    has occurred, then

    a call

    is made to

    updateCf

    ients,

    where

    all clients are

    given

    the

    new

    conflated stock

    price.

    Also,

    the

    period

    start time

    is

    reset

    to the current

    time

    in

    preparation

    of

    the new confla-

    tion

    period. The updatecl

    i ents method also

    resets

    the

    timeout

    to be

    equal to the

    full

    period,

    and

    resets the flag that

    indicates

    a

    data feed

    update

    has occurred.

    The

    code is

    now ready to call

    wai

    tForObj

    ect

    again.

    The

    DotoFeed

    Closs

    The

    DataFeed

    class

    is

    simple,

    but

    since

    it

    uses RelativeTime to

    create

    pauses

    between

    updates

    (to

    simulate

    updates arriving

    aperiodically) let's explore

    it

    now

    (see

    ListingT-7).

    Listing

    7-7 The

    DataFeed

    class

    class

    DataFeed

    extends

    RealtimeThread

    {

    private

    Object

    privlock

    =

    w

    ObjectO;

    public

    void

    runO

    {

    //

    begin

    first

    period

    send(O,

    L0.00);

    //

    starting

    price

    send(2

    ,

    -.02);

    send(1

    ,

    -.0L);

    send

    (1-

    ,

    +

    .0L)

    ;

    send(2,

    -.50)

    ;

    send(4, O.0O);

    //

    tust

    sleep

    for

    4ms

    //

    begin second

    period

    send(12,

    -.11);

    //

    update

    well

    after

    period

    ]

    private

    void send(int

    interval, double change)

    {

    if(interval>0){

    //

    Wait

    for

    elapsed

    time

    try

    {

    RelativeTime

    elaPsed

    =

    new Rel ativeTime(interval,

    0)

    ;

    synchron'i

    zed

    (

    privlock

    ) {

    Hi

    ghResol

    uti onTi

    me . wai tFor0bj ect

    (

    privlock,

    elapsed);

    ]

    ]

    catch(Exceptione){}

    ]

    if

    (

    change

    =

    O.OO

    )

    {

    update

    =

    change;

  • 8/10/2019 7. the Real-Time Clock API

    13/14

    A

    Co,tpttrs,o

    SrocxDm,

    Fm

    Ex,lturpm

    synchronized(1ock){

    lock.notifyO;

    ]

    This

    contrived

    code

    simulates

    sending

    the

    updates,

    perperiod,

    as

    shown

    in Figure

    7-4.The

    first

    parameter

    in

    the

    send

    method

    is the

    amount

    of

    time in milliseconds

    the

    code

    waits

    before

    sending

    the update.

    The

    second

    parameter

    is

    the amount

    the

    stock

    price

    has

    moved,

    up or

    down

    (a

    delta value).

    If

    the

    update

    value

    passed

    is

    zeto,the

    method

    effectively

    acts

    as

    a

    high-resolution

    call

    to

    s'leep. If

    the

    interval

    is

    set to

    zeo,

    the

    price

    update

    is

    sent

    immediately.

    Sending

    a

    price

    update is

    a

    simple

    operation;

    the

    global update

    delta value is

    set,

    and the

    shared

    lock

    object

    is

    signaled

    (informing

    the

    Conflater

    class

    that

    the

    update

    is

    available).

    The

    succession

    of

    calls

    to send

    is meant

    to simulate

    a

    random

    pattern

    of

    updates

    with

    varying

    amounts

    of time

    between

    them,

    such

    that

    they

    recreate

    the scenario

    in

    Figure

    7-4.

    Applicotion

    Output

    When

    executed

    with

    Java

    RTS

    on

    a uniprocessor,

    the following

    output

    will

    be

    observed:

    Conflater

    started...

    Conflate

    r recei

    ved

    start'i ng

    pr.i

    ce

    Conflater:

    update

    -0.02,

    Elapsed=(2

    ms,

    2484

    ns)

    Conflater:

    update

    -0.0L,

    Elapsed=(3

    ms,

    5276

    ns)

    Conflater:

    update

    0.01-,

    Elapsed=(5

    ms,

    3099 ns)

    Conflater:

    update

    -0.5,

    E'lapsed=(7

    ms,

    3104

    ns)

    Conflater:

    Updati

    ng

    c'li ents:

    Conflater:

    pri

    c=9.48

    Conflater:

    Time

    since

    last

    update:(10

    ms,

    0

    ns)

    Conflater:

    update

    -0.LL,

    E'lapsed=(13

    ms,

    5331 ns)

    Conflater:

    update

    after

    period

    Conflater:

    Updating

    clients:

    Conflater:

    pri

    ce=9.

    37

    Conflater:

    Time

    since last

    update:(13

    ms,

    5331 ns)

    Atthe

    verybeginning

    (r=

    0),

    the

    stock

    startprice

    is

    received

    andthewai

    tForobject

    loop

    begins. You

    can

    see

    in

    the output

    above

    that four

    data

    feed

    updates

    are

    conflated

    into

    the

    first

    price

    update

    sent

    out

    to

    the simulated

    clients.

    The

    time

    elapsed

    when

    each update

    is

    received

    is relative

    to

    the

    start

    of

    the

    current period (not

    to

    each

    23

  • 8/10/2019 7. the Real-Time Clock API

    14/14

    236

    Cu.prnn7

    Trun

    Rn,uTt*t

    CtocxAPI

    individual

    update).

    Therefore, the

    first

    update

    to clients

    is triggered

    by the

    period

    timeout

    att+

    l0

    milliseconds.

    However,

    during the

    second

    ten-millisecond

    period,

    no

    data

    feed

    updates occur.

    Therefore,

    when the

    period

    expires,

    nothing

    is done. When

    an

    update

    finally does

    arrive

    13

    milliseconds

    after the

    beginning

    of

    the

    second

    period (t +

    23

    millisec-

    onds), the

    new

    price

    is

    sent

    to clients

    immediately,

    and

    the

    cycle

    repeats.