学习java多线程第一部分

こ雲淡風輕ζ 提交于 2019-12-06 14:23:55

一.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 }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!