创建线程的4种方式
1、继承Thread类,复写run方法,run方法中为线程需要执行的逻辑部分,而启动线程调用start方法。小示例见代码,通过Thread.currentThread().getName()可以获得当前线程名称
public class MyThread extends Thread {
private int i;
public void run(){
for(;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
};
public static void main(String[] args) {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+""+i);
if(i==20){
new MyThread().start();
new MyThread().start();
}
}
}
2、由于java不支持多继承,当需要继承另一个类时,与第一种方式冲突。于是可以使用第二种方法,通过实现Runnable接口。复写run方法。代码下
public class MyThread2 implements Runnable{
private int i;
@Override
public void run() {
for(;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
public static void main(String[] args) {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+""+i);
if(i==20){
MyThread2 myThread2 = new MyThread2();
new Thread(myThread2).start();
new Thread(myThread2).start();
}
}
3使用callable和future,Callable()与Runable()不同的地方主要是,Callable方法有返回值。代码如下
public class CallableDemo implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int i = 5;
for(;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
return i;
}
}
public static void main(String[] args) {
CallableDemo callableDemo = new CallableDemo();
FutureTask<Integer> futureTask = new FutureTask<Integer>(callableDemo);
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+""+i);
if(i==20){
new Thread(futureTask,"有返回的线程:").start();
try {
System.out.println("子线程的返回值" + futureTask.get());
}catch(Exception e){
e.printStackTrace();
}
}
}
}
4、通过线程池创建线程,首先介绍几个相关的类:Executor,Executors,ExecutorService,Future。Executor为Java1.5后引入的一系列并发库中与executor相关的功能类。
Executors为一个创建线程的工厂,其中提供了4种创建线程的方式。
<一>创建固定数量的线程。其中参数即为固定线程的数量。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
<二>创建可缓存的线程,线程超过60s会被回收。当缓存的没有线程可以使用时,则创建新线程使用。该情况下线程是无界的,只要想使用线程会无限的创建,除非发生内存溢出。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
<三>创建一个单线程化的Executor。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
<四>创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}