Friday, November 26, 2010

Why Thread.Abort() is NOT evil

I apply the using statement quite a lot:
using(FileStream fs = new FileStream(path, mode)) {
//Do work on fs here
}


This is a syntactic sugar for the try/finally construct, eg:
FileStream fs = null;
try {
fs = new FileStream(path, mode);
//Do work on fs here
}finally{
if(fs != null)
fs.Dispose();
}


Today I was researching the java.thread.stop() method, which is deprecated because it is unsafe.

While doing so, I found multiple post stating that the same is true for .Net applications. They all seem to refer to the article "How To Stop a Thread in .NET (and Why Thread.Abort is Evil)", which claims that the exception can occur in the finally block.

Fortunately this is NOT true, but I just had to make sure:
static volatile bool done = false;
static volatile bool inFinally = false;
static void Main()
{
Thread t = new Thread(new ThreadStart(RunThread));
t.Start();

//Wait for the thread to enter the finally block
while (!inFinally)
Thread.Sleep(100);

//Abort the thread in the finally block
t.Abort();

//Provoke it by issuing a double abort exception
Thread.Sleep(100);
t.Abort();

//Now make sure the thread is done
t.Join();

//Present the results
if (!done)
Console.WriteLine("Thread.Abort() is unsafe!");
else
Console.WriteLine("Thread.Abort() is NOT evil!");
}

//An emulated thread
private static void RunThread()
{
int x = 0;
try { x = 1000; } //A harmless operation
finally
{
//Flag that we are ready for the exception
inFinally = true;
//Do some time consuming work to ensure that we
// stay in the finally block for a while
for (int i = 0; i < 10000; i++)
for (int j = 0; j < 10000; j++)
x++;

//If we did not get interrupted, set the flag
done = true;
}
}


And fortunately the output is:
Thread.Abort() is NOT evil!

Sunday, November 21, 2010

Utilizing Android LinearLayout

I have been using the Android LinearLayout for a test application. There is some documentation and a minor preview of what it does, but I don't think this makes it simple to understand.
I tried searching for a better explanation, but none came up, so here is my version.

The xml that I'm using as a base is this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="100px" android:layout_height="80px"
    android:orientation="vertical"
    >
    
    <TextView 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:layout_weight="1" 
        android:text="1"
        android:textColor="#000000"
        android:gravity="center" 
        android:background="#ff0000"
    />

    <TextView 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:layout_weight="1" 
        android:text="1"
        android:textColor="#000000"
        android:gravity="center" 
        android:background="#00ff00"
    />

    <TextView 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:layout_weight="1" 
        android:text="1" 
        android:textColor="#000000"
        android:gravity="center" 
        android:background="#0000ff"
    />
</LinearLayout>


When you set the layout_height to fill_parent and the layout_weight to the same number, the available space is divided between the elements. This makes it possible to have two or more elements sharing the available space, where each gets the same amount of space:

This was about what I could gather from the demo page. But what if you want a fixed size header, and have the two following elements share whatever space is left? The solution is to set the layout_height of the fixed-size element to wrap_content, and then set the layout_weight to 0 for that element:

This is counter-intuitive to me, because the name layout_weight is really a priority instead, so each item with the same layout_weight share the remaining space evenly. Once all elements with priority (layout_weight) 0 are placed, all elements with priority 1 then share the remaining layout space.

This lead me to investigate the reason for choosing the word weight, and it turns out that the value doubles as a weight as long as it is less than 1.0:

Friday, November 12, 2010

Java Grievances part 2

At some point the concept of a foreach construct was implemented in Java. This is a really nice construct that allows one to change code like this:

int sum = 0;
Enumeration<Integer> it = some_list.getEnumerator();
while(it.hasMoreElements())
    sum += it.nextElement();
into code like this:

int sum = 0;
for(Integer i : some_list)
    sum += i;

This is quite nice, unfortunately, it is an addon so many Java libraries has no support for this. Even some of the more prominent libraries such as org.xml.sax and java.util.Hashtable have no support for the enumeration feature, even if they are obvious candidates. Nice try, but does not really give any punch as it is mostly not usable.

This is some of the same problems that occurs when using generics, which is not supported by the Java bytecode, so all the generic types are removed during compilation (called type erasure). The benefit of this is that code can use generics internally but still expose a non-generic interface externally. If this was the programmers intention, it could be done anyway, but now the choice is not there. The reason for this is obviously compatibility, but the implications are that the libraries are forced to expose a legacy interface. The really nice way to do this would be to set a compile switch that toggles either generic output, or type erasure. Again, nice try but does not really give anything.

The other problem is in the design philosophy where Java opts for having a single get() method which then takes an enumeration value as input. The notable example is the Calendar.get function which takes a number of integer values as input and returns different things. This approach means that the programmer has to look up what values are allowed, or guess the naming convention used for this particular method. It also means that the get method must validate all input to ensure that the user supplied a valid value.

A much better approach would be to simply make different functions, as that is what it really is. Example:
Calendar today = Calendar().getInstance();
//Actual
int day = today.get(Calendar.DAY_OF_WEEK);
int month = today.get(Calendar.MONTH) + 1;

//Better?
int day = today.getDayOfWeek();
int month = today.getMonth() + 1;

That way the documentation is less required, there are no run-time errors as the programmer cannot supply an invalid value, a win-win. Well, one can dream :)

Monday, November 8, 2010

Java Grievances

I've been doing a bit of Java work lately, and I must say that I am not impressed.

The language itself is a bit dated, lacking features such as enums and properties, but the worst part is the libraries.

Something as basic as a date can be manipulated with either the java.util.Date or java.util.Calendar. There is probably a neat history to explain why one would want two different versions of the same structure, but it should not be that way. The stock library should have a one-fits-all approach.

When working with the Calendar type, the annoying use of factory patterns result in less readable code, such as:
Calendar date = Calendar.getInstance();
date.setDate(year, month - 1, day);
Rather than just:
Calendar date = new Calendar(year, month, day);

You can opt to use java.util.GregorianCalendar instead, which does allow a non-factory type initialization, but that is still one extra hurdle to work with.

As an incomprehensibly strange decision, the month numbering starts with 0, but day starts with 1 as does day of week. This makes it unnecessarily awkward to work with dates, for no apparent gain.