我是靠谱客的博主 忧郁抽屉,这篇文章主要介绍线程基础-线程的创建,现在分享给大家,希望可以做个参考。

如何创建并执行一个线程

Java中通过java.lang.Thread类来启动创建一个线程。
创建一个线程可以通过两种方法,但是最后执行都是调用Thread类的start()方法来启动一个线程。 start()会自动调用run() 执行线程的操作。

声明Thread实例创建线程

这是最基本的创建一个线程的方法,new一个Thread实例,然后调用start()方法来运行这个线程,
线程的具体执行的内容放到run()方法里面,一般使用内部类的方式来创建一个线程,也可以通过创建一个Thread类的子类来创建线程。

  • 内部类的方式
复制代码
1
2
3
4
5
6
7
8
9
10
/** * new Thread类的实例创建,然后调用start(),启动一个线程。 */ new Thread(){ @Override public void run() { System.out.println("当前线程名字为:"+Thread.currentThread().getName()); } }.start();
  • 创建Thread的子类
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** * 定义Thread的子类来创建一个线程 */ static class MyThread extends Thread { public MyThread() { setName("MyThread"); } @Override public void run() { System.out.println("当前线程名字为:"+Thread.currentThread().getName()); } } //运行线程 (new MyThread()).start();

通过Runnable接口创建一个线程。

Thread类中有一个构造方法 public Thread(Runnable var1) ,我们可以通过这个构造方法,传入一个Runnable类的实例来创建一个线程。下面是Runnable类创建线程的一个内部类实现的方式。

复制代码
1
2
3
4
5
6
7
8
9
10
/** * 使用java.lang.Runnable来创建并启动一个线程 */ new Thread(new Runnable(){ @Override public void run() { System.out.println("当前线程名字为:"+Thread.currentThread().getName()); } }).start();

下面我们看下Runnable接口的定义:

复制代码
1
2
3
4
5
package java.lang; public interface Runnable { void run(); }

Runnable接口只有个run()方法,线程的实现只能放到这个方法里面。我们知道调用Thread实例的start()开启线程后,会进入Thread实例的run()方法,那么线程又是如何和Runnable接口关联的呢,下面进入Thread类的源码查看究竟。

首先我们进入线程的构造方法的实现:

复制代码
1
2
3
4
public Thread(Runnable var1) { this.init((ThreadGroup)null, var1, "Thread-" + nextThreadNum(), 0L); }

进入Thread类的init方法。Thread类的init方法有好几个重载方法,最终进入下面这个方法

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void init(ThreadGroup var1, Runnable var2, String var3, long var4, AccessControlContext var6) { if(var3 == null) { throw new NullPointerException("name cannot be null"); } else { this.name = var3; .... this.target = var2;//Runnable的实例赋值了Thread实例的target变量中。 this.setPriority(this.priority); if(var7.inheritableThreadLocals != null) { this.inheritableThreadLocals = ThreadLocal.createInheritedMap(var7.inheritableThreadLocals); } this.stackSize = var4; this.tid = nextThreadID(); } }

通过上面的方法可以清楚的看到传入Thread的实例的Runnable实例被赋值target变量。那么target变量是什么时候调用的呢。现在进入Thread类的run方法一看究竟

复制代码
1
2
3
4
5
6
public void run() { if(this.target != null) { this.target.run(); } }

至此我们看到一个清晰的线程运行流程。

  1. Runnable实例保存到Thread实例的成员变量target中。
  2. 调用Thread实例的start()方法启动实例。
  3. 线程启动运行后,进入其run()方法。
  4. 如果target不为空,就调用其run()方法

通过ThreadFactory来创建线程实例。

先看一下ThreadFactory接口的定义:

复制代码
1
2
3
4
5
package java.util.concurrent; public interface ThreadFactory { Thread newThread(Runnable var1); }

ThreadFactory接口只有一个方法 Thread newThread(Runnable var1);.
所以通过实现ThreadFactory接口创建线程,本质上是和new Thread(Runnable var1)一样的。
但是使用new Thread(Runnable var1)创建线程,可复用差,而通过不同的ThreadFactory实现
可以创建不同的线程,是工厂方法模式的一个具体实现。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/** * 通过ThreadFactory类创建一个实例。 */ ThreadFactory factory = new ThreadFactory() { @Override public Thread newThread(Runnable runnable) { return new Thread(runnable); } }; factory.newThread(new Runnable() { @Override public void run() { System.out.println("当前线程名字为:"+Thread.currentThread().getName()); } }).start();

可以通过Executors.defaultThreadFactory()获取一个默认的线程工厂。

复制代码
1
2
3
4
5
6
7
8
9
10
/** * 通过Executors.defaultThreadFactory()获取一个ThreadFactory类,然后创建一个实例。 */ Executors.defaultThreadFactory().newThread(new Runnable() { @Override public void run() { System.out.println("当前线程名字为:"+Thread.currentThread().getName()); } }).start();

使用ExecutorService运行线程

还可以利用线程池创建一个线程,下面是一个实现例子。

复制代码
1
2
3
4
5
6
7
8
9
ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() { @Override public void run() { System.out.println("当前线程名字为:"+Thread.currentThread().getName()); } }); executorService.shutdown();

参考

  • 《图解多线程设计模式》
  • 《Java编程思想》

最后

以上就是忧郁抽屉最近收集整理的关于线程基础-线程的创建的全部内容,更多相关线程基础-线程内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(75)

评论列表共有 0 条评论

立即
投稿
返回
顶部