一、线程的创建
线程是并发编程中基础的基础,只有先了解如何创建线程,才能进一步学习并发相关的知识。
常见的实现线程的方法有以下几种:
1. Runnable接口
可以通过实现Runnable接口,并重写run()方法,之后将实现Runnable接口的类传入Thread中即可创建线程。
public class RunnableThread implements Runnable {
@Override
public void run() {
System.out.println('用实现Runnable接口实现线程');
}
}
2. Thread类
继承Thread类,重写其中的run()方法创建线程:
public class ExtendsThread extends Thread {
@Override
public void run() {
System.out.println('用Thread类实现线程');
}
}
3. 线程池
通过线程池,可以指定线程数量,由线程池创建线程。
对于线程池而言,本质上是通过线程工厂创建线程的,默认采用 DefaultThreadFactory ,它会给线程池创建的线程设置一些默认值,比如:线程的名字、是否是守护线程,以及线程的优先级等。
/**
* 描述: 用固定线程数的线程池执行10000个任务
*/
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10000; i++) {
service.execute(new Task());
}
System.out.println(Thread.currentThread().getName());
}
static class Task implements Runnable {
public void run() {
System.out.println("Thread Name: " + Thread.currentThread().getName());
}
}
}
4. 带返回值的Callable接口
实现Callable接口,并重写call()方法,之后将实现Callable接口的类传入Thread中创建线程。
这种方式与Runnable接口的方式相类似,但是Callable接口通过Future将线程执行的结果作为返回值返回。
class CallableTask implements Callable<Integer> {
@Override
public Integer call() throws Exception {
return new Random().nextInt();
}
}
//创建线程池
ExecutorService service = Executors.newFixedThreadPool(10);
//提交任务,并用 Future提交返回结果
Future<Integer> future = service.submit(new CallableTask());
5. 其他
a. 定时器
新建一个 Timer,令其每隔一段时间之后,执行一些任务,这时它也会创建线程并执行任务。
public class Run {
private static Timer timer=new Timer();
public static void main(String[] args) throws ParseException
{
timer.schedule(new Mytask(), TimeUtil.df.get().parse("2017-09-14 09:19:30"));
}
}
b. 匿名内部类或 lambda 表达式
/**
*描述:匿名内部类创建线程
*/
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}).start();
/**
*描述:lambda表达式创建线程
*/
new Thread(() -> System.out.println(Thread.currentThread().getName())).start();
}
6. 到底有几种创建线程的方法?
前面介绍了5中创建线程的方法,按理来说,创建线程的方法应该是很多的,然而实际上,创建线程的方法只有一种而已。
对于线程池而言,跟进DefaultThreadFactory 的源码查看具体创建线程的实现:
static class DefaultThreadFactory implements ThreadFactory {
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;