简介
- 程序:是为了完成特定的任务,用某种语言编写的一组指令的集合。
- 进程就是指运行中的程序,进程是程序的一次执行过程,或者是正在运行的一个程序。是一个动态的过程,有他自身的产生,存在和消亡。
- 线程是进程创建的,是进程的一个实体,一个进程可以拥有多个线程。
- 单线程同一个时刻只允许执行一个线程
- 多线程,同一个时刻,可以执行多个线程
- 并发:同一个时刻,多个任务交替执行,造成一个“貌似同时”的错觉,简单来说,单核cpu实现多任务就是并发。
- 并行:同一个时刻,多个任务同时执行,多核cpu可以实现并行。并发和并行可以同时存在,如果任务过多。
创建线程的两种方法
继承Thread类,重写run方法
练习1
每隔一秒输出一个语句,20秒结束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
public class Test { public static void main(String[] args) { Cat cat = new Cat(); cat.start(); } }
class Cat extends Thread{ int time=0; @Override public void run(){ while (true){ System.out.println("喵喵,我是小喵咪"); time++; try{ Thread.sleep(1000);}catch (Exception e){ System.out.println("发生了错误"); } if (time==20){ break; } } } }
|
通过实现Runnable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public class Test { public static void main(String[] args) { Cat cat = new Cat(); Thread thread = new Thread(cat); thread.start(); } }
class Cat implements Runnable{ @Override public void run() { while (true){ System.out.println("喵喵"); } } }
|
其实我们的底层使用了静态代理模式,而之所以可以使用Thread方法传入cat,是因为构造函数中存在Thread(Runnable),而Cat继承了Runnable。
1 2
| Thread thread = new Thread(cat); thread.start();
|
模拟线程代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class ThreadProxy implements Runnable{ private Runnable target=null; @Override public void run() { if (target!=null){ target.run(); } } public ThreadProxy(Runnable target) { this.target = target; } public void start(){ start0(); } public void start0(){ run(); } }
|
总结
其实总源码上来看,这两个创建线程的机制没有本质的区别,他们的底层都是调用start0机制进行线程的创建,而且Thread其实是调用了Runnable接口的。
但是Runnable接口更加适合多个线程共享一个资源的情况(可以将两个线程同时调用cat对象),并且避免了单继承的限制。