|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 6 of 7
There are still a few problems that have to be fixed to make this all work in the real world. For example, there's no way
for a program to know if the user overtypes a string when nobody fetches the original string before it's overwritten. Input
strings should be queued up as they come in and read_line() should return a string from the queue if there is one, blocking only if the queue is empty. Listing 3 serves to illustrate
the problem at hand without addressing these other issues.
01 | import java.awt.*;
02 | import java.awt.event.*;
03 | import com.holub.asynch.Condition;
04 |
05 | public class Input_source_fixed extends Frame
06 | {
07 | Condition text_has_been_entered = new Condition(false); // Initial condition is false
08 |
09 | TextField input = new TextField();
10 |
11 | public Input_source_fixed()
12 | {
13 | input.addActionListener
14 | ( new ActionListener()
15 | { public void actionPerformed( ActionEvent e )
16 | { text_has_been_entered.set_true(); // set the condition true
17 | }
18 | }
19 | );
20 |
21 | add(input);
22 | pack();
23 | show();
24 | }
25 |
26 | /** A blocking function that works like readLine(), but gets its
27 | * text from the current window's text area. The function doesn't
28 | * return until somebody types a line of text, whereupon it returns
29 | * the line. Returns null if the user types an empty line.
30 | */
31 |
32 | synchronized String read_line() throws InterruptedException
33 | {
34 | text_has_been_entered.wait_for_true();
35 | text_has_been_entered.set_false();
36 |
37 | String entered = input.getText();
38 | input.setText("");
39 | return (entered.length() == 0) ? null : entered;
40 |
41 | }
42 |
43 |
44 | static public void main( String[] args ) throws Exception
45 | { Input_source_fixed source = new Input_source_fixed();
46 | String input;
47 |
48 | while( (input = source.read_line()) != null )
49 | System.out.println("Got: " + input );
50 |
51 | System.exit(0); // kill the AWT Thread on exit
52 | }
53 | }
|
The other semaphore I want to look at this month is the "Djikstra" counting semaphore. This one has no direct analog in Java, so it's among the more useful of the com.holub.asynch classes.
Counting semaphores are used to keep track of the availability of a resource within a pool of limited size. For example, you might have four connections open to a database server that are simply recycled to perform multiple queries. This way, you won't incur the overhead of opening a connection every time you make a query. Threads seeking to make queries should block (should be suspended, waiting), if no connections are available. They should be reactivated (released from wait) when a connection becomes available. A counting semaphore can solve this problem (though other solutions -- such as a thread-safe stack with a pop method that blocks if the stack is empty -- are also possible).
Counting semaphores are initialized with a count -- typically the number of objects available in the pool. Every time you acquire the semaphore, the count is decremented; every time you release the semaphore, it's incremented. On acquisition, if the count (after the decrement) is non-0, nothing happens, and you get your slot in the pool. If the count is 0, however, the acquiring thread blocks until some other thread releases the semaphore, thereby incrementing the count.