• java的多线程之入门


    一.java多线程基本概念

    调用run():在主线程调用子线程的run()方法会中断主线程等到子线程执行完毕之后再执行主线程。

    调用start():在主线程中执行子线程的start()后会与主线程同步执行。

    二.线程创建的三种方法

    Thread、Runnable、Callable

    1.Thread入门

    步骤:

    • 继承Thread类
    • 重写run方法
    • 调用start开启线程
     1 //创建线程方式一步骤:继承Thread类,重写run方法,调用start开启线程
     2 public class test01 extends Thread{
     3 
     4 
     5     @Override
     6     public void run() {
     7         for (int i = 0; i < 10;i++){
     8             System.out.println("run方法执行..." + i);
     9         }
    10     }
    11 
    12     public static void main(String[] args) {
    13 
    14         //创建线程对象
    15         test01 t1 = new test01();
    16 
    17         //开启线程
    18         t1.start();
    19 
    20         for (int i = 0; i < 1000; i++){
    21             System.out.println("main方法执行..." + i);
    22         }
    23     }
    24 }

    执行结果:交替执行

    练习:使用Thread实现多线程同步下载图片

    (1).导入依赖的jar包:

    1    <dependency>
    2       <groupId>commons-io</groupId>
    3       <artifactId>commons-io</artifactId>
    4       <version>2.6</version>
    5     </dependency>

    (2).编写test02.java:

     1 /**
     2  * 使用多线程下载图片
     3  * @author USTC_WZH
     4  * @create 2019-12-05 11:26
     5  */
     6 public class test02 extends Thread {
     7 
     8 
     9     //图片url地址
    10     private String url;
    11     //保存的文件名
    12     private String name;
    13 
    14     public test02(String url, String name) {
    15         this.url = url;
    16         this.name = name;
    17     }
    18 
    19     @Override
    20     public void run() {
    21         WebDownloader webDownloader = new WebDownloader();
    22         webDownloader.downloader(url, name);
    23         System.out.println("下载文件名:" + name);
    24     }
    25 
    26     public static void main(String[] args) {
    27         test02 t1 = new test02("http://lswhw.ustc.edu.cn/upload/20150427/20150427102635.jpg", "images/图片1.jpg");
    28         test02 t2 = new test02("http://lswhw.ustc.edu.cn/upload/20150427/20150427103657.jpg", "images/图片2.jpg");
    29         test02 t3 = new test02("http://lswhw.ustc.edu.cn/upload/20150427/20150427103010.jpg", "images/图片3.jpg");
    30 
    31         t1.start();
    32         t2.start();
    33         t3.start();
    34     }
    35 }
    36 
    37 
    38 class WebDownloader {
    39 
    40     public void downloader(String url, String name) {
    41         try {
    42             FileUtils.copyURLToFile(new URL(url), new File(name));
    43         } catch (IOException e) {
    44             e.printStackTrace();
    45             System.out.println("downloader方法出现异常");
    46         }
    47     }
    48 }

    2.实现Runable接口(重点使用)

    三个步骤:

    • 实现Runnable接口,重写run方法
    • 执行线程需要丢入Runnable接口的实现类
    • 调用start方法

     1 /**
     2  * 创建线程方法二步骤:
     3  *          1.实现Runnable接口,重写run方法。
     4  *          2.执行线程需要丢入runnable接口的实现类。
     5  *          3.调用start方法。
     6  * @author USTC_WZH
     7  * @create 2019-12-05 14:14
     8  */
     9 public class test03 implements Runnable{
    10 
    11     @Override
    12     public void run() {
    13         for (int i = 0; i < 10;i++){
    14             System.out.println("run方法执行..." + i);
    15         }
    16     }
    17 
    18     public static void main(String[] args) {
    19 
    20         //创建runnable接口的实现类对象
    21         test01 t1 = new test01();
    22 
    23         //创建线程对象,通过线程对象来开启我们的线程,代理模式
    24         new Thread(t1).start();
    25 
    26         for (int i = 0; i < 1000; i++){
    27             System.out.println("main方法执行..." + i);
    28         }
    29     }
    30 }

    补充:模拟并发问题

     1 /**
     2  * 模拟买火车票
     3  *
     4  * @author USTC_WZH
     5  * @create 2019-12-05 14:32
     6  */
     7 public class testerror implements Runnable {
     8 
     9     //火车票个数
    10     private int ticketNums = 10;
    11 
    12     @Override
    13     public void run() {
    14 
    15         while (true) {
    16 
    17             if (ticketNums <= 0) {
    18                 break;
    19             }
    20 
    21             //模拟延时
    22             try {
    23                 Thread.sleep(100);
    24             } catch (InterruptedException e) {
    25                 e.printStackTrace();
    26             }
    27 
    28             System.out.println(Thread.currentThread().getName() + "-->拿了第" + ticketNums-- + "票");
    29         }
    30     }
    31 
    32     public static void main(String[] args) {
    33 
    34         testerror t = new testerror();
    35 
    36         new Thread(t, "小明").start();
    37         new Thread(t, "小红").start();
    38         new Thread(t, "花花").start();
    39     }
    40 }

    当同一个对象被多个线程访问时出现的并发错误的问题!

    3.实现Callable接口(了解)

    步骤:7步

    • 实现Callable接口,需要返回值类型
    • 重写call方法,需要抛出异常
    • 创建目标对象
    • 创建执行服务
    • 提交执行
    • 获取结果
    • 关闭服务
     1 package ustc.wzh.callable;
     2 
     3 import org.apache.commons.io.FileUtils;
     4 
     5 import java.io.File;
     6 import java.io.IOException;
     7 import java.net.URL;
     8 import java.util.concurrent.*;
     9 
    10 /**
    11  * @author USTC_WZH
    12  * @create 2019-12-05 14:44
    13  * <p>
    14  * 创建线程方式三步骤:
    15  * 1.实现Callable接口,需要返回值类型
    16  * 2.重写call方法,需要抛出异常
    17  * 3.创建目标对象
    18  * 4.创建执行服务
    19  * 5.提交执行
    20  * 6.获取结果
    21  * 7.关闭服务
    22  */
    23 //1.实现Callable接口
    24 public class testCallable implements Callable<Boolean> {
    25 
    26     //图片url地址
    27     private String url;
    28     //保存的文件名
    29     private String name;
    30 
    31     public testCallable(String url, String name) {
    32         this.url = url;
    33         this.name = name;
    34     }
    35 
    36 
    37     //2.重写call方法
    38     @Override
    39     public Boolean call() throws Exception {
    40         WebDownloader webDownloader = new WebDownloader();
    41         webDownloader.downloader(url, name);
    42         System.out.println("下载文件名:" + name);
    43         return true;
    44     }
    45 
    46     public static void main(String[] args) throws ExecutionException, InterruptedException {
    47 
    48         //创建目标对象
    49         testCallable t1 = new testCallable("http://lswhw.ustc.edu.cn/upload/20150427/20150427102635.jpg", "images/图片1.jpg");
    50         testCallable t2 = new testCallable("http://lswhw.ustc.edu.cn/upload/20150427/20150427103657.jpg", "images/图片2.jpg");
    51         testCallable t3 = new testCallable("http://lswhw.ustc.edu.cn/upload/20150427/20150427103010.jpg", "images/图片3.jpg");
    52 
    53         //4.创建执行服务
    54         ExecutorService ser = Executors.newFixedThreadPool(3);
    55 
    56         //5.提交执行
    57         Future<Boolean> r1 = ser.submit(t1);
    58         Future<Boolean> r2 = ser.submit(t2);
    59         Future<Boolean> r3 = ser.submit(t3);
    60 
    61         //6.获取结果
    62         boolean rs1 = r1.get();
    63         boolean rs2 = r2.get();
    64         boolean rs3 = r3.get();
    65 
    66         System.out.println("rs1=" + rs1 + ",rs2=" + rs2 + ",rs3=" + rs3);
    67 
    68         //7.关闭服务
    69         ser.shutdownNow();
    70     }
    71 
    72 
    73 }
    74 
    75 class WebDownloader {
    76 
    77     public void downloader(String url, String name) {
    78         try {
    79             FileUtils.copyURLToFile(new URL(url), new File(name));
    80         } catch (IOException e) {
    81             e.printStackTrace();
    82             System.out.println("downloader方法出现异常");
    83         }
    84     }
    85 }
  • 相关阅读:
    Java访问Oracle服务器
    easyUI之练习
    easyUI之Tree(树)
    easyUI之Messager(消息窗口)
    easyUI之表单
    easyUI之Dialog(对话框窗口)
    easyUI之函数
    easyUI之window窗口
    easyUI之progressbar进度条
    easyUI之slider滑动条框
  • 原文地址:https://www.cnblogs.com/zhihaospace/p/11989652.html
Copyright © 2020-2023  润新知