一、程序、进程、线程
- 程序。程序是指令和数据的有序集合,其本身没有任何运 行的含义,是一个静态的概念。
- 进程则是执行程序的一次执行过程,它是一个动态的概念。是系统资源分配的单位通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没 有存在的意义。
- 线程是CPU调度和执行的的单位。
普通方法调用和多线程
二、线程的三种创建方式
1、继承Thread类
//创建线程方法一:继承Thread,重写run方法,通过strat开启线程
public class TestThread1 extends Thread{
@Override
public void run() {
//线程体
for (int i = 0; i < 200 ; i++) {
System.out.println("这是子线程"+i);
}
}
public static void main(String[] args) {
TestThread1 testThread1 = new TestThread1();//创建一个线程对象
testThread1.start();//开启线程
for (int i = 0; i < 2000; i++) {
System.out.println("这是主线程"+i);
}
}
}
例子:网图下载
//下载网络图片
public class TestThread2 extends Thread{
private String url;
private String name;
public TestThread2(String url,String name){
this.url=url;
this.name=name;
}
@Override
public void run() {
WebDowload webDowload = new WebDowload();
webDowload.download(url,name);
System.out.println("下载文件名"+name);
}
public static void main(String[] args) {
TestThread2 t1 = new TestThread2("https://i0.hdslb.com/bfs/sycp/creative_img/202202/b4125fd26982faaab87aad4ea93c09c4.jpg", "s1.jpg");
t1.start();
TestThread2 t2 = new TestThread2("https://i0.hdslb.com/bfs/sycp/creative_img/202202/b4125fd26982faaab87aad4ea93c09c4.jpg", "s2.jpg");
t2.start();
TestThread2 t3 = new TestThread2("https://i0.hdslb.com/bfs/sycp/creative_img/202202/b4125fd26982faaab87aad4ea93c09c4.jpg", "s3.jpg");
t3.start();
}
}
//下载器
class WebDowload{
//下载方法
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异常,download方法异常");
}
}
}
2、实现Runnable接口
- 定义MyRunnable类实现Runnable接口
- 实现run()方法,编写线程执行体
- 创建线程对象,调用start()方法启动线程:new.Thread(thread).start();
//创建线程,实现runnable,重写run
//执行线程需要丢入runnable接口实现类,调用start
public class TestThread3 implements Runnable{
@Override
public void run() {
//线程体
for (int i = 0; i < 200 ; i++) {
System.out.println("这是子线程"+i);
}
}
public static void main(String[] args) {
//创建一个runnable接口的实现类的对象
TestThread3 t1 = new TestThread3();
//创建线程对象,通过线程对象来开启我的线程
Thread thread = new Thread(t1);
thread.start();//开启线程
for (int i = 0; i < 2000; i++) {
System.out.println("这是主线程"+i);
}
}
}
(推荐使用runnable:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用)
3、实现Callable接口
- 1.实现Callable接口,需要返回值类型
- 2. 重写call方法,需要抛出异常
- 3. 创建目标对象
- 4. 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
- 5. 提交执行:Future<Boolean> result1 = ser.submit(t1);
- 6. 获取结果:boolean r1 = result1.get()
- 7. 关闭服务:ser.shutdownNow();
-
//下载网络图片 public class TestThread2 implements Callable<Boolean> { private String url; //下载地址 private String name; //存储名称 //构造方法 public TestThread2(String url,String name){ this.url=url; this.name=name; } @Override public Boolean call() throws Exception { WebDowload webDowload = new WebDowload(); webDowload.download(url,name); System.out.println("下载文件名"+name); return true; } public static void main(String[] args) { TestThread2 t1 = new TestThread2("https://i0.hdslb.com/bfs/sycp/creative_img/202202/b4125fd26982faaab87aad4ea93c09c4.jpg", "s1.jpg"); TestThread2 t2 = new TestThread2("https://i0.hdslb.com/bfs/sycp/creative_img/202202/b4125fd26982faaab87aad4ea93c09c4.jpg", "s2.jpg"); TestThread2 t3 = new TestThread2("https://i0.hdslb.com/bfs/sycp/creative_img/202202/b4125fd26982faaab87aad4ea93c09c4.jpg", "s3.jpg"); //创建执行任务 ExecutorService ser = Executors.newFixedThreadPool(3); //提交执行 Future<Boolean> s1 = ser.submit(t1); Future<Boolean> s2 = ser.submit(t2); Future<Boolean> s3 = ser.submit(t3); //获取结果 try { boolean res1 = s1.get(); boolean res2 = s2.get(); boolean res3 = s3.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } //关闭服务 ser.shutdown(); } }
略