第一种:直接继承Thread
public class Thread1 extends Thread {
public void run() {
int i = 4;
while (i > 0) {
i--;
System.out.print(i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new Thread1().start();
}
}
}
第二种:使用Thread的匿名内部类
public class Thread2 {
static Thread[] arr = new Thread[5];
public Thread2() {
for (int i = 0; i < 5; i++) {
arr[i] = new Thread() {
public void run() {
int i = 4;
while (i > 0) {
i--;
System.out.print(i);
}
}
};
}
}
public static void main(String[] args) {
new Thread2();
for (Thread t : arr) {
t.start();
}
}
}
第三种:继承Runnable
public class Thread3 implements Runnable {
@Override
public void run() {
int i = 4;
while (i > 0) {
i--;
System.out.print(i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new Thread(new Thread3()).start();
}
}
}
第四种:使用Runnable的匿名内部类
public class Thread4 {
static Thread[] arr = new Thread[5];
public Thread4() {
for (int i = 0; i < 5; i++) {
arr[i] = new Thread(new Runnable() {
@Override
public void run() {
int i = 4;
while (i > 0) {
i--;
System.out.print(i);
}
}
});
}
}
public static void main(String[] args) {
new Thread4();
for (Thread t : arr) {
t.start();
}
}
}
第五种:继承java.util.concurrent.Callable<T> 接口,然后实现该接口的call() 方法,这个call方法会返回泛型接口所指定的返回类型,启动线程是调用java.util.concurrent.ExecutorService的submit方法,即可得到该线程的返回值
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Thread5 implements Callable<String> {
@Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
List<Future<String>> list = new ArrayList<Future<String>>();
for (int i = 0; i < 5; i++) {
list.add(exec.submit(new Thread5()));
}
for (Future<String> str : list) {
System.out.println(str.toString());
}
exec.shutdown();
}
}
上面就是JAVA创建多形式的几种形式。
在上面的例子中,启动线程都是通过实例化线程并调用线程的start() 方法来启动线程,在java.util.concurrent中为我们提供了一种新的方便实例化线程并自动运行线程的方法,示例如下:
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class MyRunnable implements Runnable {
@Override
public void run() {
int i = 4;
while(i > 0){
i--;
System.out.print(i);
}
}
public static void main(String[] args) {
Executor exec = Executors.newCachedThreadPool();
for(int i=0;i<5;i++){
exec.execute(new MyRunnable());
}
}
}
首先通过Executors.newCachedThreadPool()创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们,此时exec是java.util.concurrent.ThreadPoolExecutor对象,当调用其exec方法时将会帮你实例化并启动线程。
Executors类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口,比较重要的方法:
Ø newCachedThreadPool():创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。
Ø newFixedThreadPool(int nThreads):创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
Ø newScheduledThreadPool(intcorePoolSize):创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。