线程的概念

线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。

每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。 当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:

调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。 非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。【1】

线程的创建

创建新执行线程有两种方法。

一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的run 方法。

1.将类声明为 Thread 的子类

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
public class MyThread extends Thread { private String info; public MyThread(String info) { this.info = info; } @Override public void run() { for(int i = 0; i < 5; i++) { System.out.println(info+" == "+i); } } }

测试类

  [java]
1
2
3
4
5
6
7
8
9
public class Main { public static void main(String[] args) { MyThread myThread = new MyThread("线程1"); MyThread myThread2 = new MyThread("线程2"); myThread.start(); myThread2.start(); } }

结果

  [plaintext]
1
2
3
4
5
6
7
8
9
10
线程1 == 0 线程2 == 0 线程1 == 1 线程2 == 1 线程1 == 2 线程2 == 2 线程1 == 3 线程2 == 3 线程1 == 4 线程2 == 4

2.创建线程的另一种方法是声明实现 Runnable 接口的类。

  • 该类然后实现 run 方法。然后可以分配该类的实例,在创建Thread 时作为一个参数来传递并启动。
  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class RunnableDemo implements Runnable{ private String name; public RunnableDemo(String name) { this.name = name; } @Override public void run() { for(int i = 0; i < 5; i++) { System.out.println(this.name + " " + i); } } }

测试-01

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
public class RunnableTest { public static void main(String[] args) { Runnable runnable = new RunnableDemo("张一"); Runnable runnable2 = new RunnableDemo("张二"); // runnable.run(); // runnable2.run(); Thread thread = new Thread(runnable); Thread thread1 = new Thread(runnable2); thread.start(); thread1.start(); } }

结果-01

  [plaintext]
1
2
3
4
5
6
7
8
9
10
张二 0 张二 1 张一 0 张一 1 张一 2 张一 3 张一 4 张二 2 张二 3 张二 4

测试-02

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
public class RunnableTest { public static void main(String[] args) { Runnable runnable = new RunnableDemo("张一"); Runnable runnable2 = new RunnableDemo("张二"); runnable.run(); runnable2.run(); // Thread thread = new Thread(runnable); // Thread thread1 = new Thread(runnable2); // thread.start(); // thread1.start(); } }

结果-02

  [plaintext]
1
2
3
4
5
6
7
8
9
10
张一 0 张一 1 张一 2 张一 3 张一 4 张二 0 张二 1 张二 2 张二 3 张二 4

线程小结

1.RunnableDemo中写了2个测试,是为了说明一个问题:

启动线程的方式——Thread对象上调用start()方法,而非run()或者别的方法。run()方法并不启动新的线程。

2.拓展(以下内容可跳过)

  [java]
1
2
3
public class Thread extends Object implements Runnable

Thread是Runnable接口的实现类。查看Thread源码,实现run()方法如下:

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } }

1.target是什么?

  [java]
1
2
/* What will be run. */ private Runnable target;

2.target的初始化?

  [java]
1
2
3
4
5
6
7
8
9
10
/** * Allocates a new {@code Thread} object. This constructor has the same * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} * {@code (null, null, gname)}, where {@code gname} is a newly generated * name. Automatically generated names are of the form * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer. */ public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); }
  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** * Allocates a new {@code Thread} object. This constructor has the same * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} * {@code (null, target, gname)}, where {@code gname} is a newly generated * name. Automatically generated names are of the form * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer. * * @param target * the object whose {@code run} method is invoked when this thread * is started. If {@code null}, this classes {@code run} method does * nothing. */ public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); }

3.init是什么?

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** * Initializes a Thread. * * @param g the Thread group * @param target the object whose run() method gets called * @param name the name of the new Thread * @param stackSize the desired stack size for the new thread, or * zero to indicate that this parameter is to be ignored. * @param acc the AccessControlContext to inherit, or * AccessController.getContext() if null */ private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) { //... }

4.Thread的start()方法

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/** * Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread. * <p> * The result is that two threads are running concurrently: the * current thread (which returns from the call to the * <code>start</code> method) and the other thread (which executes its * <code>run</code> method). * <p> * It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed * execution. * * @exception IllegalThreadStateException if the thread was already * started. * @see #run() * @see #stop() */ public synchronized void start() { //... }

相关内容

线程-001-线程简介

线程-002-基本的线程机制

线程-003-线程的同步与锁

线程-004-线程间的协作及状态迁移

资料引用