一.进程(Process)
1.程序是指令和数据的有序集合,是一个静态的概念
2.进程是执行程序的一次执行过程,是一个动态的概念
3.一个进程可以包含了多个线程,一个进程至少有一个线程(Thread),线程是CPU调度和执行的单位
二.线程是如何实现的
1.由类继承Thread,并且重写run()方法,最后在主方法中,使用start()方法,启动线程。两个线程是同时一起运行的
package Thread;
public class Demo1 extends Thread {
@Override
public void run() {
for(int i = 0;i <20;i++){
System.out.println("这是一个多线程"+i);
}
}
public static void main(String[] args) {
Demo1 demo1 = new Demo1();
demo1.start();
for(int i = 0;i<20;i++){
System.out.println("这是一个主进程"+i);
}
}
}
三.编写一个多图片下载器
1.首先是引入一个工具包common.io,之后开始编写
2.在类中定义一个下载器,需要传入下载地址url,和文件名
3.重写构造器,需要传入url和name,两个参数
4.重写run()方法,将url和name传入构造器中
5.写出主函数,运行该方法
package Thread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//练习Thread,实现多线程同步下载
public class Demo2 extends Thread{
private String url;
private String name;
public Demo2(String url , String name){
this.name = name;
this.url = url;
}
@Override
public void run() {
WebDownload webDownload = new WebDownload();
webDownload.Download(url,name);
System.out.println("下载了图片"+name);
}
public static void main(String[] args) {
Demo2 t1 = new Demo2("https://i0.hdslb.com/bfs/archive/57b9cbf30ed1f68938a6b23c2222919929c5fea5.jpg@336w_190h_1c_!web-rec-list.avif","baobao1.jpg");
Demo2 t2 = new Demo2("https://i2.hdslb.com/bfs/archive/389a3feb291967c08342e1805d4955afaa072693.jpg@336w_190h_1c_!web-rec-list.avif","baobao2.jpg");
Demo2 t3 = new Demo2("https://i1.hdslb.com/bfs/archive/163b76bb950c3e5c257d478a60f46b642fbd5388.jpg@336w_190h_1c_!web-rec-list.avif","baobao3.jpg");
t1.start();
t2.start();
t3.start();
}
}
class WebDownload{
public void Download(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常");
}
}
}
四.实现runnable接口
1.首先的区别在于,他是runnable 的实现类,之后再通过new Thread来实现启动
package Thread;
public class Demo3 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("这是一个多线程" + i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
System.out.println("这是一个主线程" + i);
}
Demo3 t = new Demo3();
//此时的Demo3是runnable的实现类,所以没有start方法来启动,需要重新定义
Thread thread = new Thread(t);//将runnable的实现对象丢入Thread,才可以启动线程
thread.start();
new Thread(t).start();//可以简写为这个
}
}
在日常开发中,尽量使用runnable接口的实现,而不直接使用继承Thread的原因是:
1.使用Runnable,避免了使用继承Thread造成的面向对象(OOP)单继承的局限性
2.使用Runnable,灵活方便,方便了同一个对象被多个线程使用