进程的概念
通俗来讲,启动电脑中的一个exe文件就叫启动一个进程。“进程是一个静态的概念”,在我们机器中实际上运行的都是线程。Linux和Widows都是支持多进程多线程的操作系统,DOS只支持单线程
线程的概念
引用马士兵老师的解释:“线程是一个程序中不同的执行路径”
示例
public class Test {
public static void main(String[] args) {
m1();
}
static void m1() {
m2();
m3();
}
static void m2() {}
static void m3() {}
}
分析上面程序的执行路径有几条
上图就是程序执行的顺序,只有一条路径,所以这个程序是单线程的
在一个时间点内,一个CPU只支持一个线程运行,只不过CPU运行速度很快,所以感觉是多线程运行
- Main方法也叫主线程
- Java的线程是通过java.lang.Thread类来实现的
- JVM启动时会有一个主方法public static void main()所定义的线程
- 可以通过创建Thread的实例来创建新的线程
- 每个线程都是通过某个特定的Thread对象所对应的run()方法来完成操作的,方法run()称为线程体
- 可以通过调用Thread类的start()方法来启动一个线程
线程的创建和启动
有两种方式创建新的线程
第一种
- 定义线程类实现Runnable接口
- Thread myThread = new Thread(target) target为Runnable接口类型
- Runnable中只有一种方法:public void run():用于定义线程运行体
- 使用Runnable接口可以为多个线程提供共享的数据
- 在实现Runnable接口的类的run方法定义中可以使用Thread的静态方法:public static Thread currentThread() 获取当前线程的引用
第二种
- 可以定义一个Thread的子类并重写其run方法
class MyThread extends Thread{
public void run(){
...
}
}
通过实现Runnable接口实现线程创建
public class TestThread1{
public static void main(String[] args){
Runner1 r = new Runner1();//创建了一个线程
Thread t = new Thread(r);//准备启动一个线程
t.start();
for(int i = 0;i < 100;i++)
System.out.println("Main Thread:-------" + i);
}
}
class Runner1 implements Runnable{
public void run(){
for(int i = 0;i < 100;i++)
System.out.println("Runner1:" + i);
}
}
运行结果如下图所示:
可以看到,两条输出交错打印,实现了多线程,用一个图来表示线程的运行过程:
这两个线程其实是交替在执行,或者说并行运行
下面再看一个代码
public class TestThread1{
public static void main(String[] args){
Runner1 r = new Runner1();
r.run();
for(int i = 0;i < 100;i++)
System.out.println("Main Thread:-------" + i);
}
}
class Runner1 implements Runnable{
public void run(){
for(int i = 0;i < 100;i++)
System.out.println("Runner1:" + i);
}
}
执行这个代码会先打印Runner1中的所有输出语句,然后再打印Main中的输出语句,这不叫创建线程,这个叫方法调用,两者是天壤之别
通过继承Thread类实现线程创建
public class TestThread1 {
public static void main(String[] args) {
Runner1 r = new Runner1();
r.start();
for(int i = 0;i < 100;i++)
System.out.println("Main Thread:-------" + i);
}
}
class Runner1 extends Thread{
public void run(){
for(int i = 0;i < 100;i++)
System.out.println("Runner1:" + i);
}
}
总结
要实现多线程,必须实例化Thread类,调用其start()方法
两种创建线程的方式,推荐使用实现接口的方式,如果使用继承的方式就不能再继承其他的类,但是实现接口可以