Below is our implementation.
import java.util.Random;
public class Bubble {
    private int sortArraySize = 10000;
	int nThreads = 8;
	int unSorted[];
	int sorted[];
	int mTid = 0;
	Object tidLock;
	int oneUnit = 0;
	int syncCnt = 0;
	Object syncCntLock;
	int arraySeed = 12345;
	long baseTime = 0;
    private int[] prepareData()
    {
        int toSort[] = new int[sortArraySize];
        Random random = new Random(arraySeed);
        for(int i = 0; i < sortArraySize; i++)
            toSort[i] = random.nextInt();
        return toSort;
    }
    class workerThread implements Runnable
    {
		private int myId;
		private void sort(int toSort[], int stIdx, int edIdx)
        {
            boolean done = true;
            for(int i = edIdx; i >= 0; i--)
            {
                int j = (stIdx + i) - 1;
                for(int k = stIdx; k < j; k++)
                    if(toSort[k] > toSort[k + 1])
                    {
                        int tmp = toSort[k];
                        toSort[k] = toSort[k + 1];
                        toSort[k + 1] = tmp;
                        done = false;
                    }
                if(done)
                    return;
                done = true;
            }
        }
		public void run()
		{
        	synchronized (tidLock)
			{
		    	myId = mTid++;
			}
        	long curTime;
        	curTime = System.currentTimeMillis();
        	System.out.println("["+myId+"] "+"sort begin, ms "+(curTime-
baseTime));
    		sort(unSorted, myId * oneUnit, oneUnit);
    		curTime = System.currentTimeMillis();
    		System.out.println("["+myId+"] "+"sort end, ms "+(curTime-
baseTime));
			synchronized (syncCntLock)
			{
				syncCnt++;
				if (syncCnt == nThreads)
					syncCntLock.notifyAll();
			}
		}
    }
    public void doMain()
    {
    	baseTime = System.currentTimeMillis();
        unSorted = prepareData();
		oneUnit  = sortArraySize / nThreads;
        for(int i = 0; i < nThreads; i++)
            (new Thread(new workerThread())).start();
		synchronized (syncCntLock)
		{
			try
			{
				if (syncCnt != nThreads)
					syncCntLock.wait();
			}
			catch (Exception e)
			{
				throw new RuntimeException("Wait Failed!" + e.getMessage());
			}
		}
		long curTime = System.currentTimeMillis();
		System.out.println("======================");
    	System.out.println("Total time, ms: "+(curTime-baseTime));
    }
    Bubble()
    {
    	tidLock = new Object();
    	syncCntLock = new Object();
    }
    Bubble(int threadNum)
    {
    	tidLock = new Object();
    	syncCntLock = new Object();
    	nThreads = threadNum;
    }
    public static void main(String[] args) {
    	boolean androidTracing = false;
    	int threadNum = 8;
    	String traceFile = "bubbletrace";
    	System.out.println("argument: [threadnum] ");
    	if (args.length >= 1)
    	{
    		threadNum = Integer.parseInt(args[0], 10);
		if ((threadNum < 1) || (threadNum > 8))
				threadNum = 8;
    	}
    	System.out.println("Using " + threadNum + " threads..");
    	Bubble bubble = new Bubble(threadNum);
    	bubble.doMain();
> > 
android-platfo...@googlegroups.com<android-platform%2Bunsubscrib 
e...@googlegroups.com>
> > .