java多线程基础

发布时间 2023-04-12 20:27:19作者: 旧歌

多线程实现方法

第一种方法:Thread

  • 自定义线程类继承Thread类

  • 重写run()方法,编写线程执行体

  • 创建线程对象,调用start()方法启动线程

  • 注意:线程不一定立即执行,由CPU安排调度

继承Thread类创建多线程

package com.waves.dxcdemo;

import java.text.DateFormat;
import java.time.format.DateTimeFormatter;
import java.util.Date;

//创建多线程方式一:继承Thread类,重写run()方法,调用start开启线程
//总结 线程开启子线程不一定立即执行 ,由cpu调度执行
public class TestThread1 extends Thread{
   @Override
   public void run() {
       //线程方法体
       for (int i = 0; i < 20; i++) {
           System.out.println("2021-11-28 18:22 多线程代码"+i);
      }
  }

   public static void main(String[] args) {
       //main方式,主线程
       TestThread1 thread1 = new TestThread1();
       thread1.start();  //调用start方法,run 与 下方学习代码交替执行

      // thread1.run(); //调用run方法,优先执行run方法体的业务代码

//       Date date = new Date();
//       long time = date.getTime();

       for (int i = 0; i < 20; i++) {
           System.out.println("2021-11-28 18:22 学习多线程代码"+ i);
      }
  }
}

继承Thread类使用多线程同步下载图片

package com.waves.dxcdemo;


import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

//练习Thread,实现多线程同步下载图片
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() {
       WedDownLoader wedDownLoader = new WedDownLoader();
       wedDownLoader.downLoader(url,name);
       //图片保存在根目录
       System.out.println("下载图片路径为"+url+"\n"+"下载的图片名字为"+name);
  }

   public static void main(String[] args) {
       TestThread2 xiancheng1 = new TestThread2("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fd.zdqx.com%2Fshirt_20190710%2F014.jpg&refer=http%3A%2F%2Fd.zdqx.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1641202820&t=637cea2d77c04500bdbef46abce0e64e","动漫桌面1.jpg");
       TestThread2 xiancheng2 = new TestThread2("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2Fba794af4e3c6a4cf93b25f19e148dc4288e58b91.jpg&refer=http%3A%2F%2Fi0.hdslb.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1641203074&t=0b47d29f43a86fc5a2adae8bb5b60748","动漫桌面2.jpg");
       TestThread2 xiancheng3 = new TestThread2("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2Fc099d5c83bdffb17eff062d5298eb136f558b8fd.jpg&refer=http%3A%2F%2Fi0.hdslb.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1641203131&t=490c5ea40c0745215a8140d8118f22ec","动漫桌面3.jpg");

       //三个线程,同时按照从上往下的顺序执行   同时线程也不是立即执行,看CPU安排调度
       xiancheng1.start();
       xiancheng2.start();
       xiancheng3.start();
  }

}

//下载器
class WedDownLoader{

   public void downLoader(String url,String name){
       try {
           FileUtils.copyURLToFile(new URL(url),new File(name));
      } catch (IOException e) {
           e.printStackTrace();
           System.out.println("IO异常,DownLoader下载异常");
      }
  }
}

第二种:实现Runable接口

  • 定义实现MyRunnable类实现Runnable接口

  • 实现Run()方法,编写线程执行体

  • 创建线程对象,调用start()方法启动线程

  • 注意:推荐使用Runnable对象,因为Java单继承的局限性

package com.waves.dxcdemo;

public class TestThread3 implements Runnable{
   @Override
   public void run() {
       //线程方法体
       for (int i = 0; i < 200; i++) {
           System.out.println("2021-11-28 18:22 多线程代码"+i);
      }
  }

   public static void main(String[] args) {
       //main方式,主线程
       TestThread3 thread3 = new TestThread3();
       //创建线程对象,通过线程对象来开启我们的线程,也就是代理
//       Thread thread = new Thread(thread3);
//       thread.start();
//合并为一句代码
       new Thread(thread3).start();

       for (int i = 0; i < 200; i++) {
           System.out.println("2021-11-28 18:22 学习多线程代码"+ i);
      }
  }
}

 

继承Thread类和实现Runnable接口-小结:

  • 继承Thread类

    • 子类继承Thread类具备多线程能力

    • 启动线程:子类对象.start()

    • 不建议使用:避免OOP单继承局限性

  • 实现Runnable接口

    • 实现接口Runnable具有多线程能力

    • 启动线程:传入目标对象+Thread对象.start()

    • 推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用