Tuesday, November 9, 2010

Executor Completion Service

Scenario: you want to load the tasks in parallel and then wait for the completion of all the tasks.


//Callable is different from Runnable that it returns result
private final class StringTask extends Callable<String>{
public String call(){
//Long operations
return "Run";
}
}

ExecutorService threadPool = Executors.newFixedThreadPool(4);
CompletionService<String> pool = new ExecutorCompletionService<String>(threadPool);

for(int i = 0; i < 10; i++){
pool.submit(new StringTask());
}

//you have the result in the order they are completed and you don’t have to keep a
//collection of Future
for(int i = 0; i < 10; i++){
String result = pool.take().get();

//Compute the result
}
threadPool.shutdown();

See: Java Concurrency: Executors and Thread Pools

MySQL Commands

- Enable/disable MySQL general log (query log)


% set global general_log = 'ON' (or 'OFF')

The file is output to hostname.log by default or we can specify file name in my.ini with "log=fileName"

- Turn on/off Foreign Key checks for dropping schema

% set foreign_key_checks = 1; (or 0 to turn off)

- Check version

% status;

Monday, November 8, 2010

Two Linked Structures

- LinkedBlockingQueue
It makes sure all the jobs will be executed sequentially. The take() method retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

- LinkedHashMap
It maintains a doubly-linked list internally and keep the order that the key is inserted.

Wednesday, November 3, 2010

JMX Service URL

JMX service URL could be in either JNDI form or encoded form.

JNDI form: the RMI stub is acquired from external such as RMI registry

Encoded form: the generated stub is encoded and attached in service url itself. So no RMI registry is required.

The JMX service URL has the following syntax:

service:jmx:rmi://[host[:port]][urlPath]

Although host and port may be included, they are ignored by the RMI protocol. If urlPath is specified, it gives the Java Naming and Directory Interface (JNDI) location of an RMI stub (typically a location within an RMI registry) in the form

/jndi/jndiName

For example, the URL

service:jmx:rmi://myhost/jndi/rmi://myhost:1099/myhost/myjmxconnector

specifies an RMI stub at the location

rmi://myhost:1099/myhost/myjmxconnector

which is an RMI registry running at location myhost/myjmxconnector on port 1099 of host myhost.

Alternatively, if urlPath is omitted from the service URL, the JMX connector server will generate a client URL containing the actual RMI stub embedded within it in encoded and serialized form. For example, the service URL

service:jmx:rmi://localhost

will generate a client URL of the form

service:jmx:rmi://localhost/stub/rmiStub

where rmiStub is an encoded and serialized representation of the RMI stub itself.


// Get the platform MBeanServer
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();

// Attach a JMXConnectorServer to the platform MBeanServer
JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///");
JMXConnectorServer connectorServer =
JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, mbeanServer);
connectorServer.start();

// Refresh the JMXServiceURL after the JMXConnectorServer has started
// it is different with the original one with the stub object attached.
jmxServiceURL = connectorServer.getAddress();


See:
JMX Service URL example
JMX remoting API
JMX Service URLs

Monday, November 1, 2010

Notify and Wait

Two things to be noticed:
1) notify() and wait() need to be used inside a synchronized block. They are used for release/acquire object lock.

2) In getMessage() method, notify() is called at first beginning. It doesn't actually release the lock atm, as stated in API "Wakes up a single thread that is waiting on this object's monitor...The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object."


import java.util.Vector;

class Producer extends Thread {
static final int MAXQUEUE = 5;
private Vector messages = new Vector();

public void run() {
try {
while ( true ) {
putMessage();
sleep( 1000 );
}
}
catch( InterruptedException e ) { }
}

private synchronized void putMessage()
throws InterruptedException {

while ( messages.size() == MAXQUEUE )
wait();
messages.addElement( new java.util.Date().toString() );
notify();
}

// Called by Consumer
public synchronized String getMessage()
throws InterruptedException {
notify();
while ( messages.size() == 0 )
wait();
String message = (String)messages.firstElement();
messages.removeElement( message );
return message;
}
}

class Consumer extends Thread {
Producer producer;

Consumer(Producer p) {
producer = p;
}

public void run() {
try {
while ( true ) {
String message = producer.getMessage();
System.out.println("Got message: " + message);
sleep( 2000 );
}
}
catch( InterruptedException e ) { }
}

public static void main(String args[]) {
Producer producer = new Producer();
producer.start();
new Consumer( producer ).start();
}
}



See: Exploring Java: Threads