`

Java线程创建方式

阅读更多

1、定义任务

线程可以驱动任务,因此需要一种描述任务的方式,这可以由Runnable接口来提供,要想定义任务,只需实现Runnable接口并编写run()方法,使得该任务可以执行你的命令,要想实现线程行为,必须显式地将一个任务附着到线程上,例如:

import java.util.*;

public class TimePrinter implements Runnable {
	int pauseTime;
	String name;

	public TimePrinter(int x, String n) {
		pauseTime = x;
		name = n;
	}

	public void run() {
		while (true) {
			try {
				System.out.println(name + ":"+ new Date(System.currentTimeMillis()));
				Thread.sleep(pauseTime);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	static public void main(String args[]) {
		//将任务附着到Thread上
		Thread t1 = new Thread(new TimePrinter(1000, "Fast Guy"));
		t1.start();
		Thread t2 = new Thread(new TimePrinter(3000, "Slow Guy"));
		t2.start();
	}

}

 

2、Thread 类

Thread 类是一个具体的类,即不是抽象类,该类封装了线程的行为。要创建一个线程,程序员必须创建一个从 Thread 类导出的新类。程序员必须覆盖 Thread 的 run() 函数来完成有用的工作。用户并不直接调用此函数;而是必须调用 Thread 的 start() 函数,该函数再调用 run()。

 

import java.util.*;

public class TimePrinter extends Thread {
	int pauseTime;
	String name;

	public TimePrinter(int x, String n) {
		pauseTime = x;
		name = n;
	}

	public void run() {
		while (true) {
			try {
				System.out.println(name + ":"+ new Date(System.currentTimeMillis()));
				Thread.sleep(pauseTime);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	static public void main(String args[]) {
		TimePrinter thread1=new TimePrinter(1000, "Fast Guy");
		thread1.start();
	}

}

 

3、使用Executor

Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等

并发编程的一种编程方式是把任务拆分为一些列的小任务,即Runnable,然后在提交给一个Executor执行,Executor.execute(Runnalbe)

 

Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定数目线程的线程池。

public static ExecutorService newCachedThreadPool()

创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

public static ExecutorService newSingleThreadExecutor()

创建一个单线程化的Executor。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。

 

Executor executor = Executors.newFixedThreadPool(10);
Runnable task = new Runnable() {
	@Override
	public void run() {
		System.out.println("task over");
	}
};
executor.execute(task);

executor = Executors.newScheduledThreadPool(10);
ScheduledExecutorService scheduler = (ScheduledExecutorService) executor;
scheduler.scheduleAtFixedRate(task, 10, 10, TimeUnit.SECONDS);

 

4、使用Callable,Future返回结果

 

Future<V>代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则,get()会使当前线程阻塞。FutureTask<V>实现了Future<V>和Runable<V>。Callable代表一个有返回值得操作。

 

		Callable<Integer> func = new Callable<Integer>(){
			public Integer call() throws Exception {
				System.out.println("inside callable");
				Thread.sleep(1000);
				return new Integer(8);
			}		
		};		
		FutureTask<Integer> futureTask  = new FutureTask<Integer>(func);
		Thread newThread = new Thread(futureTask);
		newThread.start();
		
		try {
			System.out.println("blocking here");
			Integer result = futureTask.get();
			System.out.println(result);
		} catch (InterruptedException ignored) {
		} catch (ExecutionException ignored) {
		}

 

ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics