Friday, December 26, 2014

ExecutorService Conundrum

I was asked by someone to solve a problem with threads that they were having. They wanted to cancel a Future that was sent to an ExecutorService. I told them to look at a previous posts I had done on the subject. However, they insisted that this was different. So I took a look at the code. Alas, it was slightly different, but like most folks including me, they were too close to the problem to see the answer. I looked at it, and at first glance I thought something was askew, but it was not.

The code for this project can be downloaded here: runnable-example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
--- exec-maven-plugin:1.2.1:exec (default-cli) @ runnable-example ---
Future cancelled? false
Future done? false
Future cancelled? true
Future done? true
Interrupted
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Interrupted
Breaking out of run loop.
As you can see from the results of the run, the future is canceled, but still keeps running. Then it gets interrupted, and breaks. So the question is why is it still running after being canceled.

Here is the Runnable and the main class to execute it:

MyRunnable.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.bluelotussoftware.examples.threads;
 
/**
 *
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0
 */
public class MyRunnable implements Runnable {
 
    private int counter = 0;
 
    @Override
    public void run() {
 
        boolean running = true;
 
        while (running) {
            try {
                Thread.sleep(1000);
                System.out.println("Sleeping...");
 
            } catch (InterruptedException e) {
                counter++;
                System.out.println("Interrupted");
                if (counter > 1) {
                    System.out.println("Breaking out of run loop.");
                    running = false;
                }
            }
        }
    }
}

Main.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.bluelotussoftware.examples.threads;
 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
 
/**
 *
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0
 */
public class Main {
 
    public static void main(String[] args) throws InterruptedException {
        // Example #1 Old School
//        Thread t = new Thread(new MyRunnable());
//        t.start();
//        Thread.sleep(5000);
//        t.interrupt();
//        Thread.sleep(2000);
//        t.interrupt();
 
        // Example #2
        ExecutorService es = Executors.newSingleThreadExecutor();
        MyRunnable r = new MyRunnable();
        Future<?> future = es.submit(r);
 
        // Sleep the current thread
 
        // Check the future
        System.out.println("Future cancelled? " + future.isCancelled());
        System.out.println("Future done? " + future.isDone());
 
        future.cancel(true);
 
        // Check to make sure it really is canceled.
        System.out.println("Future cancelled? " + future.isCancelled());
        System.out.println("Future done? " + future.isDone());
 
        // Execute an orderly shutdown of our service.
        es.shutdown();
 
        // Wait patiently for 10 seconds for the Threads to cleanup
        if (!es.awaitTermination(10, TimeUnit.SECONDS)) {
            // Kill the service regardless of Thread state.
            es.shutdownNow();
        }
    }
 
}
So the do you have an answer? The answer is at the bottom of the blog. Don't peek... think!

Reference

Answer

Simply because you have canceled it, and even interrupted it; it is still a running thread. It is not scheduled, so you are not canceling it before execution.

Sunday, December 21, 2014

JSF 2.x Dynamic Encoding

Encoding Examples
In an Internationalized world, we need to be able to change the encoding of a JSF page dynamically. In this case, we have some characters encoded in UTF-8, but we want to be able to change the encoding on the page, and have the framework handle the character conversions for our web page.

So how do we do it?

One of the simplest ways is to wrap our page in a <f:view /> tag. The tag wraps the <head/> and <body/> elements in our HTML page. In the example above this is accomplished as shown below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">
    <f:view encoding="#{encodingBean.encoding}">
        <h:head>
            <title>모든 좋은 사람들이 자신의 나라의 원조에 오기를이 시간입니다</title>
        </h:head>
        <h:body>
            <h1>
Encoding Examples</h1>
<p>
                JSF handles encoding very well. If you don't believe it, change the encoding in the dropdown menu,
                and then check the page source of the rendered page.
            </p>
<p>
                This example uses UTF-8 encoded text, and then allows the user to switch the encoding type.
                Note that JSF handles most cases, but some cases are not covered. Here is the original quote:
            </p>
<blockquote>
                <h:outputText value="#{encodingBean.weller}"/>
            </blockquote>
<h2>
Translated Quotes</h2>
<h:outputText value="Tämä on aikaa kaikille hyvää miestä tulla auttamaan maansa"/> (Finnish)
             
 
 
            Tämä on aikaa kaikille hyvää miestä tulla auttamaan maansa (Finnish)
             
 
             
 
            這是時間對所有的好男人來到他們的國家的援助 (Chinese - Simplified)
             
 
 
            모든 좋은 사람들이 자신의 나라의 원조에 오기를이 시간입니다 (Korean)
             
 
            <h:form id="form1">
                <h:selectOneMenu value="#{encodingBean.encoding}"  onchange="document.forms['form1'].submit();">
                    <f:selectItems value="#{encodingBean.items}"/>
                </h:selectOneMenu>
            </h:form>
        </h:body>
    </f:view>
</html>
The code for the backing bean is shown below:

EncodingBean.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.bluelotussoftware.encoding;
 
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
 
/**
 *
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0
 */
@ManagedBean
@ViewScoped
public class EncodingBean implements Serializable {
 
    private static final long serialVersionUID = -2585222706903579334L;
 
    private String encoding = "UTF-8";
    private final String weller = "Now is the time for all good men to come to the aid of their country";
 
    public EncodingBean() {
    }
 
    public String getEncoding() {
        return encoding;
    }
 
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }
 
    public List<selectitem> getItems() {
        List<selectitem> items = new ArrayList<>();
        SortedMap<String, Charset> charsets = Charset.availableCharsets();
        Set<string> keys = charsets.keySet();
        for (String key : keys) {
            items.add(new SelectItem(key));
        }
 
        return items;
    }
 
    public String getWeller() {
        return weller;
    }
 
}
The Netbeans Maven project can be found here: JSF Dynamic Encoding

Popular Posts