学习线程时,最令我印象深入的就是那种不肯定性、没有保障性,各个线程的运行彻底是以不可预料的方式和速度推动,有的一个程序运行了N次,其结果差别性很大。一步一步来,首先让咱们看看什么是线程。
线程是彼此互相独立的、能独立运行的子任务,而且每一个线程都有本身的调用栈。所谓的多任务是经过周期性地将CPU时间片切换到不一样的子任务,虽然从微观上看来,单核的CPU上同时只运行一个子任务,可是从宏观来看,每一个子任务彷佛是同时连续运行的。
在java中,线程指两个不一样的内容:一是java.lang.Thread类的一个对象;另外也能够指线程的执行。线程对象和其余的对象同样,在堆上建立、运行、死亡。但不一样之处是线程的执行是一个轻量级的进程,有它本身的调用栈。
能够这样想,每一个调用栈都对应一个线程,每一个线程又对应一个调用栈。咱们运行java程序时有一个入口函数main()函数,它对应的线程被称为主线程。一个新线程一旦被建立,就产生一个新调用栈,从原主线程中脱离,也就是与主线程并发执行。
在Java中建立线程有两种方法:使用Thread类和使用Runnable接口。在使用Runnable接口时须要创建一个Thread实例。所以,不管是经过Thread类仍是Runnable接口创建线程,都必须创建Thread类或它的子类的实例。下面看一下建立并启动线程的例子:
Java代码
public
class MyThread
extends Thread {
private String threadName;
public
void run() {
for (
int i = 0; i < 20; i++) {
this.currentThread().getName();
System.out.println(Thread.currentThread().getName());
if (
this.threadName.equals(
"A"))
System.out.println(
"线程" +
this.threadName +
"在计数:" + i);
else
if(
this.threadName.equals(
"B"))
System.out.println(
"--------线程" +
this.threadName +
"在计数:" + i);
}
}
public MyThread(String name) {
super(name);
this.threadName = name;
}
public MyThread() {
super();
}
public
static
void main(String args[]) {
MyThread mt1 =
new MyThread(
"A");
mt1.start();
MyThread mt2 =
new MyThread(
"B");
mt2.start();
}
}
运行结果为:
A
B
--------线程B在计数:0
B
--------线程B在计数:1
B
--------线程B在计数:2
B
--------线程B在计数:3
B
--------线程B在计数:4
B
--------线程B在计数:5
B
--------线程B在计数:6
B
--------线程B在计数:7
B
--------线程B在计数:8
B
--------线程B在计数:9
线程A在计数:0
A
线程A在计数:1
A
线程A在计数:2
A
线程A在计数:3
A
线程A在计数:4
A
线程A在计数:5
A
线程A在计数:6
A
线程A在计数:7
A
线程A在计数:8
A
线程A在计数:9
A
线程A在计数:10
A
线程A在计数:11
A
线程A在计数:12
A
线程A在计数:13
A
B
--------线程B在计数:10
B
--------线程B在计数:11
B
--------线程B在计数:12
B
--------线程B在计数:13
B
线程A在计数:14
A
线程A在计数:15
A
线程A在计数:16
A
线程A在计数:17
A
线程A在计数:18
A
线程A在计数:19
--------线程B在计数:14
B
--------线程B在计数:15
B
--------线程B在计数:16
B
--------线程B在计数:17
B
--------线程B在计数:18
B
--------线程B在计数:19
另外一个建立线程的方式:
Java代码
public
class RunableThread
implements Runnable {
private String threadName;
public
void run() {
for (
int i = 0; i < 100; i++) {
if (
this.threadName.equals(
"A"))
System.out.println(
"线程" +
this.threadName +
"在计数:" + i);
else
if (
this.threadName.equals(
"B"))
System.out.println(
"--------线程" +
this.threadName +
"在计数:" + i);
}
}
public
static
void main(String[] args) {
RunableThread r1 =
new RunableThread(
"A");
Thread t1 =
new Thread(r1);
RunableThread r2 =
new RunableThread(
"B");
Thread t2 =
new Thread(r2);
t1.start();
t2.start();
}
}
线程会以如下三种方式之一结束
(1) 线程到达其run()方法的末尾;
(2) 线程抛出一个未捕获到得Exception或Error;
(3) 另外一个线程调用一个Deprecated的 stop() 方法。这个方法会引发线程的安全问题,已经不推荐使用了.因此不要调用这个方法