Execution in Java always take form of a thread. In simple programs only one thread occurs, often referred to as the 'main thread'.
In some programs though concurrent threads is necessary, or if you are building a Swing application with for example a progress bar you don't want the main thread to handle the updates of the UI.
Then you create an additional thread to take care of that. There are two main ways of creating a thread. The first is to extend the Thread class and the second is to implement the Runnable interface.
Extending Thread:
public class MyThread extends Thread {
/**
* This method is executed when the start() method is called on the thread
* so here you will put the 'thread code'.
*/
public void run() {
System.out.println("Thread executed!");
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Thread thread = new MyThread();
thread.start();
}
}
Implementing the Runnable interface:
public class MyRunnable implements Runnable {
/**
* As in the previous example this method is executed
* when the start() method is called on the thread
* so here you will put the 'thread code'.
*/
public void run() {
System.out.println("Thread executed!");
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
//create a Thread object and pass it an object of type Runnable
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
Wednesday, May 27, 2009
Setting thread priorities
Setting a threads priority can be very useful if one thread has more critical tasks to perform than another.
The Thread class has a method called setPriority(int level) with which you can alter the priority a Thread instance has.
The priority level range from 1 (least important) to 10 (most important) and if no level is explicitly set, a Thread instance has the priority level of 5.
In the first example below no priorites are set, so both threads have the priority level 5. The TestThread class implements the Runnable interface and in its
run() method loops from 1 to 10 and output the number along with its Thread id, which is passed to the constructor.
/**
* Main.java
*
* @author
*/
public class Main {
/**
* Starts two threads and wait for them to finish.
*/
public void setPrioritiesOnThreads() {
Thread thread1 = new Thread(new TestThread(1));
Thread thread2 = new Thread(new TestThread(2));
thread1.start();
thread2.start();
try {
//Wait for the threads to finish
thread1.join();
thread2.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Done.");
}
/**
* Starts the program
*
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().setPrioritiesOnThreads();
}
class TestThread implements Runnable {
int id;
public TestThread(int id) {
this.id = id;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread" + id + ": " + i);
}
}
}
}
Since both threads have the same priority, the output will be a mix between them and could look like this:
Thread2: 1
Thread1: 1
Thread2: 2
Thread1: 2
Thread2: 3
Thread1: 3
Thread2: 4
Thread1: 4
Thread2: 5
Thread1: 5
Thread2: 6
Thread1: 6
Thread2: 7
Thread2: 8
Thread2: 9
Thread2: 10
Thread1: 7
Thread1: 8
Thread1: 9
Thread1: 10
Done.
The output could look different from on execution to another since we have no control of how the CPU will prioritize them.
If we set the priority on the threads we still haven't got exact control of the execution, but at least we can tell the CPU which one we think is
most important. The next example is identical to the one above except for the lines where the priority of the threads are set:
/**
* Main.java
*
* @author
*/
public class Main {
/**
* Starts two threads, setting priorities on them
* and wait for them to finish.
*
*/
public void setPrioritiesOnThreads() {
Thread thread1 = new Thread(new TestThread(1));
Thread thread2 = new Thread(new TestThread(2));
//Setting priorities on the Thread objects
thread1.setPriority(Thread.MAX_PRIORITY);
thread2.setPriority(Thread.MIN_PRIORITY);
thread1.start();
thread2.start();
try {
//Wait for the threads to finish
thread1.join();
thread2.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Done.");
}
/**
* Starts the program
*
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().setPrioritiesOnThreads();
}
class TestThread implements Runnable {
int id;
public TestThread(int id) {
this.id = id;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread" + id + ": " + i);
}
}
}
}
The output from the code looked like this when executed:
Thread1: 1
Thread1: 2
Thread1: 3
Thread1: 4
Thread1: 5
Thread1: 6
Thread1: 7
Thread1: 8
Thread1: 9
Thread1: 10
Thread2: 1
Thread2: 2
Thread2: 3
Thread2: 4
Thread2: 5
Thread2: 6
Thread2: 7
Thread2: 8
Thread2: 9
Thread2: 10
Done.
It is however not certain that the first thread will be prioritized to finish before the second thread starts every time.
It is, as mentioned earlier, up to the CPU to decide.
The Thread class has a method called setPriority(int level) with which you can alter the priority a Thread instance has.
The priority level range from 1 (least important) to 10 (most important) and if no level is explicitly set, a Thread instance has the priority level of 5.
In the first example below no priorites are set, so both threads have the priority level 5. The TestThread class implements the Runnable interface and in its
run() method loops from 1 to 10 and output the number along with its Thread id, which is passed to the constructor.
/**
* Main.java
*
* @author
*/
public class Main {
/**
* Starts two threads and wait for them to finish.
*/
public void setPrioritiesOnThreads() {
Thread thread1 = new Thread(new TestThread(1));
Thread thread2 = new Thread(new TestThread(2));
thread1.start();
thread2.start();
try {
//Wait for the threads to finish
thread1.join();
thread2.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Done.");
}
/**
* Starts the program
*
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().setPrioritiesOnThreads();
}
class TestThread implements Runnable {
int id;
public TestThread(int id) {
this.id = id;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread" + id + ": " + i);
}
}
}
}
Since both threads have the same priority, the output will be a mix between them and could look like this:
Thread2: 1
Thread1: 1
Thread2: 2
Thread1: 2
Thread2: 3
Thread1: 3
Thread2: 4
Thread1: 4
Thread2: 5
Thread1: 5
Thread2: 6
Thread1: 6
Thread2: 7
Thread2: 8
Thread2: 9
Thread2: 10
Thread1: 7
Thread1: 8
Thread1: 9
Thread1: 10
Done.
The output could look different from on execution to another since we have no control of how the CPU will prioritize them.
If we set the priority on the threads we still haven't got exact control of the execution, but at least we can tell the CPU which one we think is
most important. The next example is identical to the one above except for the lines where the priority of the threads are set:
/**
* Main.java
*
* @author
*/
public class Main {
/**
* Starts two threads, setting priorities on them
* and wait for them to finish.
*
*/
public void setPrioritiesOnThreads() {
Thread thread1 = new Thread(new TestThread(1));
Thread thread2 = new Thread(new TestThread(2));
//Setting priorities on the Thread objects
thread1.setPriority(Thread.MAX_PRIORITY);
thread2.setPriority(Thread.MIN_PRIORITY);
thread1.start();
thread2.start();
try {
//Wait for the threads to finish
thread1.join();
thread2.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Done.");
}
/**
* Starts the program
*
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().setPrioritiesOnThreads();
}
class TestThread implements Runnable {
int id;
public TestThread(int id) {
this.id = id;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread" + id + ": " + i);
}
}
}
}
The output from the code looked like this when executed:
Thread1: 1
Thread1: 2
Thread1: 3
Thread1: 4
Thread1: 5
Thread1: 6
Thread1: 7
Thread1: 8
Thread1: 9
Thread1: 10
Thread2: 1
Thread2: 2
Thread2: 3
Thread2: 4
Thread2: 5
Thread2: 6
Thread2: 7
Thread2: 8
Thread2: 9
Thread2: 10
Done.
It is however not certain that the first thread will be prioritized to finish before the second thread starts every time.
It is, as mentioned earlier, up to the CPU to decide.
Remove duplicate items from an ArrayList
This code example shows how to remove duplicate items from an ArrayList.
ArrayList arrayList1 = new ArrayList();
arrayList1.add("A");
arrayList1.add("A");
arrayList1.add("B");
arrayList1.add("B");
arrayList1.add("B");
arrayList1.add("C");
//Create a HashSet which allows no duplicates
HashSet hashSet = new HashSet(arrayList1);
//Assign the HashSet to a new ArrayList
ArrayList arrayList2 = new ArrayList(hashSet) ;
//Ensure correct order, since HashSet doesn't
Collections.sort(arrayList2);
for (Object item : arrayList2)
System.out.println(item);
Note that you will have to sort the ArrayList if you want to be sure that the items remain
in correct order by calling the sort method of the Collection class.
This will produce the following output:
A
B
C
Creating and storing arrays in a map
Sometimes you want to create variable names dynamically, for example in a loop. One way of doing this is to not create the variables with different names but rather to store them in a Collection object that takes a key-value pair.
You can provide a unique key for the variable and then store its reference as the value.
In this examples first method we create 9 arrays which we store in a Map, each with different names. In the example below we use a TreeMap.
In the second method we print out the names of each key, and loop through the values of its value object (which is an array).
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
/**
*
* @author
*/
public class Main {
Map map = new TreeMap();
/**
* Example method for creating and storing arrays in a map
*/
public void createArrays() {
for (int i = 1; i <= 9; i++) {
int[] array = new int[3];
array[0] = i;
array[1] = i + 1;
array[2] = i + 2;
map.put(("array_" + i), array);
}
}
/**
* Example method for printing arrays stored in a map
*/
public void printArrays() {
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
String arrayName = iter.next();
int[] array = map.get(arrayName);
System.out.println("Values for array " + arrayName + ":");
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
System.out.println();
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Main main = new Main();
main.createArrays();
main.printArrays();
}
}
The output of the code above will be:
Values for array array_1:
1
2
3
Values for array array_2:
2
3
4
Values for array array_3:
3
4
5
Values for array array_4:
4
5
6
Values for array array_5:
5
6
7
Values for array array_6:
6
7
8
Values for array array_7:
7
8
9
Values for array array_8:
8
9
10
Values for array array_9:
9
10
11
You can provide a unique key for the variable and then store its reference as the value.
In this examples first method we create 9 arrays which we store in a Map, each with different names. In the example below we use a TreeMap.
In the second method we print out the names of each key, and loop through the values of its value object (which is an array).
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
/**
*
* @author
*/
public class Main {
Map
/**
* Example method for creating and storing arrays in a map
*/
public void createArrays() {
for (int i = 1; i <= 9; i++) {
int[] array = new int[3];
array[0] = i;
array[1] = i + 1;
array[2] = i + 2;
map.put(("array_" + i), array);
}
}
/**
* Example method for printing arrays stored in a map
*/
public void printArrays() {
Iterator
while (iter.hasNext()) {
String arrayName = iter.next();
int[] array = map.get(arrayName);
System.out.println("Values for array " + arrayName + ":");
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
System.out.println();
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Main main = new Main();
main.createArrays();
main.printArrays();
}
}
The output of the code above will be:
Values for array array_1:
1
2
3
Values for array array_2:
2
3
4
Values for array array_3:
3
4
5
Values for array array_4:
4
5
6
Values for array array_5:
5
6
7
Values for array array_6:
6
7
8
Values for array array_7:
7
8
9
Values for array array_8:
8
9
10
Values for array array_9:
9
10
11
Convert a List (ArrayList) to an Array
This piece of Java code shows how to convert a List, in this case an ArrayList, to an Array by calling the method toArray() on the List object.
The toArray() method returns an array of the same type as the array provided as an argument to the method. The argument can be an empty array as in the example below.
/**
*
* @author
*/
public class Main {
public void ListToArray() {
List carList = new ArrayList();
carList.add("Dodge");
carList.add("Chevrolet");
carList.add("BMW");
carList.add("Toyota");
String[] carArray = carList.toArray(new String[0]);
for (String car : carArray) {
System.out.println(car);
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().ListToArray();
}
}
The code above generate the following output (the elements are ordered similarly in the array as in the list):
Dodge
Chevrolet
BMW
Toyota
The toArray() method returns an array of the same type as the array provided as an argument to the method. The argument can be an empty array as in the example below.
/**
*
* @author
*/
public class Main {
public void ListToArray() {
List
carList.add("Dodge");
carList.add("Chevrolet");
carList.add("BMW");
carList.add("Toyota");
String[] carArray = carList.toArray(new String[0]);
for (String car : carArray) {
System.out.println(car);
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().ListToArray();
}
}
The code above generate the following output (the elements are ordered similarly in the array as in the list):
Dodge
Chevrolet
BMW
Toyota
Convert a List to a Set (ArrayList to HashSet)
This example shows how to convert from an ArrayList to a HashSet. Since most Collection objects have a constructor that allows for passing in another Collection object we are able to make these kinds of conversions easily.
In the example we create an ArrayList to which we add a few string items. Next we create a HashSet and provide the reference to the ArrayList as argument to the HashSet constructor.
Finally we just loop through the HashSet and print out the contents.
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*
* @author
*/
public class Main {
/**
* Conversion from a List to a Set,
* or from an ArrayList to a HashSet object
*/
public void convertFromListToSet() {
List fruitsList = new ArrayList ();
fruitsList.add("Apples");
fruitsList.add("Bananas");
fruitsList.add("Oranges");
fruitsList.add("Grapes");
Set fruitsSet = new HashSet(fruitsList);
for (Object theFruit : fruitsSet)
System.out.println(theFruit);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().convertFromListToSet();
}
}
The output from the code is not surprisingly the items in the same order as added to the ArrayList:
Apples
Bananas
Oranges
Grapes
In the example we create an ArrayList to which we add a few string items. Next we create a HashSet and provide the reference to the ArrayList as argument to the HashSet constructor.
Finally we just loop through the HashSet and print out the contents.
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*
* @author
*/
public class Main {
/**
* Conversion from a List to a Set,
* or from an ArrayList to a HashSet object
*/
public void convertFromListToSet() {
List fruitsList = new ArrayList ();
fruitsList.add("Apples");
fruitsList.add("Bananas");
fruitsList.add("Oranges");
fruitsList.add("Grapes");
Set fruitsSet = new HashSet(fruitsList);
for (Object theFruit : fruitsSet)
System.out.println(theFruit);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().convertFromListToSet();
}
}
The output from the code is not surprisingly the items in the same order as added to the ArrayList:
Apples
Bananas
Oranges
Grapes
Convert LinkedList to Array
This code example shows how to convert a LinkedList containing Strings to an array of Strings.
We begin by creating and populating the LinkedList with String representing different fruits. The actual conversion is done by calling the toArray() method of the list which returns the array. As input we create an empty String-array to tell the method to which type the elements should be converted.
There is actually another way of doing the conversion. Instead of passing an empty array to the toArray() method, we can pass an array of the same size as the List, and then it'll be populated with the elements. See an example further below.
package com.javadb.examples;
import java.util.LinkedList;
import java.util.List;
/**
*
* @author
*/
public class Main {
public void convertLinkedListToArray() {
List theList = new LinkedList();
theList.add("Apples");
theList.add("Bananas");
theList.add("Oranges");
theList.add("Grapes");
String[] fruits = theList.toArray(new String[0]);
for (int i = 0; i < fruits.length; i++) {
System.out.println(fruits[i]);
}
}
public static void main(String[] args) {
new Main().convertLinkedListToArray();
}
We could also have done the conversion like this:
String[] fruits = new String[theList.size()];
theList.toArray(fruits);
The output looks like this:
Apples
Bananas
Oranges
Grapes
We begin by creating and populating the LinkedList with String representing different fruits. The actual conversion is done by calling the toArray() method of the list which returns the array. As input we create an empty String-array to tell the method to which type the elements should be converted.
There is actually another way of doing the conversion. Instead of passing an empty array to the toArray() method, we can pass an array of the same size as the List, and then it'll be populated with the elements. See an example further below.
package com.javadb.examples;
import java.util.LinkedList;
import java.util.List;
/**
*
* @author
*/
public class Main {
public void convertLinkedListToArray() {
List
theList.add("Apples");
theList.add("Bananas");
theList.add("Oranges");
theList.add("Grapes");
String[] fruits = theList.toArray(new String[0]);
for (int i = 0; i < fruits.length; i++) {
System.out.println(fruits[i]);
}
}
public static void main(String[] args) {
new Main().convertLinkedListToArray();
}
We could also have done the conversion like this:
String[] fruits = new String[theList.size()];
theList.toArray(fruits);
The output looks like this:
Apples
Bananas
Oranges
Grapes
List drives
This piece of code might come in handy on a Windows platform to list the drives of a computer.
import java.io.File;
public class FileUtil {
public void listDrives() {
File[] drives = File.listRoots();
for (int i = 0; i < drives.length; i++) {
System.out.println(drives[i]);
}
}
public static void main(String[] args) {
FileUtil fileutil = new FileUtil();
fileutil.listDrives();
}
}
import java.io.File;
public class FileUtil {
public void listDrives() {
File[] drives = File.listRoots();
for (int i = 0; i < drives.length; i++) {
System.out.println(drives[i]);
}
}
public static void main(String[] args) {
FileUtil fileutil = new FileUtil();
fileutil.listDrives();
}
}
Masking a password with the Console class
In Java 6 you can use the Console class to mask a password, or more precisely, no characters will be written as output to the console at all when you type the password.
This is achieved with help of the readPassword() method of the Console class. The method returns an array of char, which then easily is passed to the String class constructor to make it useful.
This example is best run in the console and not from within an IDE, since the System.console() method might return null in that case.
import java.io.Console;
/**
*
* @author
*/
public class Main {
/**
* Example method for entering password from the console
*/
public void passwordExample() {
Console console = System.console();
if (console == null) {
System.out.println("Couldn't get Console instance, maybe you're running this from within an IDE?");
System.exit(0);
}
console.printf("Testing password%n");
char passwordArray[] = console.readPassword("Enter your secret password: ");
console.printf("Password entered was: %s%n", new String(passwordArray));
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().passwordExample();
}
}
This is achieved with help of the readPassword() method of the Console class. The method returns an array of char, which then easily is passed to the String class constructor to make it useful.
This example is best run in the console and not from within an IDE, since the System.console() method might return null in that case.
import java.io.Console;
/**
*
* @author
*/
public class Main {
/**
* Example method for entering password from the console
*/
public void passwordExample() {
Console console = System.console();
if (console == null) {
System.out.println("Couldn't get Console instance, maybe you're running this from within an IDE?");
System.exit(0);
}
console.printf("Testing password%n");
char passwordArray[] = console.readPassword("Enter your secret password: ");
console.printf("Password entered was: %s%n", new String(passwordArray));
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().passwordExample();
}
}
Using the RandomAccessFile class
This java code example illustrates how you can use the RandomAccessFile class.
The example in itself might seem pretty useless but the purpose is to show that you can both write to and read from a file with the same RandomAccessFile instance.
The RandomAccessFile class also enables you to get the current position of the file pointer by calling the method 'getFilePointer', or setting the file pointer position by calling the 'seek' method.
The behaviour of the RandomAccessFile class is similar to an array in the filesystem, but unlike an array you can alter the length of the file by calling the 'setLength' method.
If you are calling seek and then start to write data in an area that already contains data, it will be overwritten.
In this example we write two lines of code to the file, then we set the file pointer to the position at the end of the first line and read data from there and print it out.
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
*
* @author
*/
public class Main {
/**
* Example method for using the RandomAccessFile class
*/
public void testRandomAccessFile(String filename) {
RandomAccessFile randomAccessFile = null;
try {
//Declare variables that we're going to write
String line1 = "First line\n";
String line2 = "Second line\n";
//Create RandomAccessFile instance with read / write permissions
randomAccessFile = new RandomAccessFile(filename, "rw");
//Write two lines to the file
randomAccessFile.writeBytes(line1);
randomAccessFile.writeBytes(line2);
//Place the file pointer at the end of the first line
randomAccessFile.seek(line1.length());
//Declare a buffer with the same length as the second line
byte[] buffer = new byte[line2.length()];
//Read data from the file
randomAccessFile.read(buffer);
//Print out the buffer contents
System.out.println(new String(buffer));
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (randomAccessFile != null)
randomAccessFile.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().testRandomAccessFile("myFile.txt");
}
}
The output to the file is:
First line
Second line
and the output to the console:
Second line
The example in itself might seem pretty useless but the purpose is to show that you can both write to and read from a file with the same RandomAccessFile instance.
The RandomAccessFile class also enables you to get the current position of the file pointer by calling the method 'getFilePointer', or setting the file pointer position by calling the 'seek' method.
The behaviour of the RandomAccessFile class is similar to an array in the filesystem, but unlike an array you can alter the length of the file by calling the 'setLength' method.
If you are calling seek and then start to write data in an area that already contains data, it will be overwritten.
In this example we write two lines of code to the file, then we set the file pointer to the position at the end of the first line and read data from there and print it out.
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
*
* @author
*/
public class Main {
/**
* Example method for using the RandomAccessFile class
*/
public void testRandomAccessFile(String filename) {
RandomAccessFile randomAccessFile = null;
try {
//Declare variables that we're going to write
String line1 = "First line\n";
String line2 = "Second line\n";
//Create RandomAccessFile instance with read / write permissions
randomAccessFile = new RandomAccessFile(filename, "rw");
//Write two lines to the file
randomAccessFile.writeBytes(line1);
randomAccessFile.writeBytes(line2);
//Place the file pointer at the end of the first line
randomAccessFile.seek(line1.length());
//Declare a buffer with the same length as the second line
byte[] buffer = new byte[line2.length()];
//Read data from the file
randomAccessFile.read(buffer);
//Print out the buffer contents
System.out.println(new String(buffer));
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (randomAccessFile != null)
randomAccessFile.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().testRandomAccessFile("myFile.txt");
}
}
The output to the file is:
First line
Second line
and the output to the console:
Second line
Subscribe to:
Posts (Atom)
