线程和进程的区别
- 一个进程是有多个线程组成的,一个进程有多个线程
- 线程是程序的最小的执行单元,进程是系统分配的最小单元
- 线程的切换是比进程切换的快
先来看下没有开启线程下来执行两次for的结果
for(int i = 0 ;i<5;i++) {
System.out.println("I:" + i);
}
for(int j = 0 ;j<5;j++) {
System.out.println("J:" + j);
}
这个是一个简单的程序,来看下执行的结果
I:0
I:1
I:2
I:3
I:4
//========================
J:0
J:1
J:2
J:3
J:4
这里会发现第二次打印在第一次打印完成之后才开始执行的。
来举一个例子:比如我现在要抓取一个网站上的图片数据,这个网站上的图片数据有很多,我不光要抓取这个网站上的图片数据,同时我还要将这些图片写到我本地的磁盘上。
这个时候如果单单的使用一个线程来处理这个数据是不是很慢,所以这时要使用多个线程来共同完成这些数据的处理。
如何创建一个线程
- 通过继承Thread
- 实现Runnable
通过继承Thread的方式
class MyThread extends Thread{
@Override
public void run() {
for(int i = 0 ;i<5;i++) {
System.out.println("I:" + i);
}
}
}
使用方式
MyThread my = new MyThread();
my.start();
和原来的代码替换
public static void main(String args[]) {
MyThread my = new MyThread();
my.start();
for(int j = 0 ;j<5;j++) {
System.out.println("J:" + j);
}
}
结果
I:0
J:0
I:1
J:1
I:2
J:2
I:3
I:4
J:3
J:4
这样发现这两个for是交替的执行的
这里为啥的交替执行(个人理解,不对的请指出)
JVM的线程调度使用的是优先级的调度方式:优先让优先级比较高的先运行。如果有两个相同优先级的线程则随机一个线程来运行。这个运行的线程会一直在运行,直到运行完成或是因为某一种原因导致不得不放弃运行。
线程的生命周期
在一个线程在创建出来到死亡要经历5种状态:新建、就绪、运行、阻塞、死亡
注意事项
这里多提一点:在启动一个线程的时候,要调用线程的start方法,不要调用线程的run方法。如果调用了run方法,系统会把比线程当成普通的方法来处理。
当我点击了my.run();会跳到MyThread的run方法,这样就直接执行了这个方法,不在是一个子线程的方法
在run上的注释写出了在Thread的子类中要重写这个run
方法
通过实现Runnable创建线程
- 线程类需要实现Runnable接口
- 使用此类时,需要将此类的对象当作一个参数放到Thread的构造中
通过Thread类的对象调用start()【这里的start并没有启动该线程,有疑问看上面的生命周期图】,执行线程
class MyRunnThread implements Runnable{ @Override public void run() { for(int i = 0 ;i<5;i++) { System.out.println("I:" + i); } } }
创建线程
Thread thread = new Thread(new MyRunnThread());
thread.start();
在上面说到的通过继承Thread类创建线程其实Thread类出是实现了Runnable的接口