Java多线程学习——01

1.核心概念

  • 程序:是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念

  • 进程Process:是执行程序的一次执行过程,它是一个动态的概念,是系统资源分配的单位、

  • 通常在一个进程中可以包含若干个线程Thread,当然一个进程中至少有一个线程,不然没有存在的意义。线程是CPU调度和执行的单位

  • 线程就是独立的执行路径。在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程、gc线程;main()称之为主线程,为系统的入口,用于执行整个程序

  • 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为干预的。对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制。线程会带来额外的开销,如CPU调度时间,并发控制开销。每个线程在自己的工作内存交互,内存控制不当会造成数据不一致。

2.线程的创建

  • 三种创建方式:Thread Class 继承Thread类

    ​ Runnable接口 实现Runnable接口(重点)

    ​ Callable接口 实现Callable接口(了解)

  • 自定义线程类继承Thread类>>重写run()方法,编写线程执行体>>创建线程对象,调用start()方法启动线程

//创建线程方式之一:继承Thread类,重写run()方法,调用start线程//总结:线程开启不一定立即执行,由CPU调度执行
public class TestThread1 extends Thread{@Overridepublic void run() {//run()方法线程体for (int i = 0; i < 20; i++) {System.out.println("我在看代码————"+i);}}public static void main(String[] args) {//main线程,主线程//创建一个线程对象TestThread1 testThread1 = new TestThread1();//调用start方法开启线程testThread1.start();for (int i = 0; i < 20; i++) {System.out.println("我在学习多线程————"+i);}}
}

3.继承Thread类和实现Runnable接口对比

  • 创建线程方式一:继承Thread类,重写run()方法,调用start线程
  • 创建线程方式二:实现runnable,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
  • 继承Thread类和实现Runnable接口对比,这里需要引入commons-io工具包实现网络下载
//创建线程方式之一:继承Thread类,重写run()方法,调用start线程
//总结:线程开启不一定立即执行,由CPU调度执行
public class TestThread1 extends Thread{@Overridepublic void run() {//run()方法线程体for (int i = 0; i < 20; i++) {System.out.println("我在看代码————"+i);}}public static void main(String[] args) {//main线程,主线程//创建一个线程对象TestThread1 testThread1 = new TestThread1();//调用start方法开启线程testThread1.start();for (int i = 0; i < 20; 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;}//下载图片线程的执行体@Overridepublic void run() {WebDownloader webDownloader = new WebDownloader();webDownloader.downloader(url,name);System.out.println("下载了文件名为:"+name);}public static void main(String[] args) {TestThread2 t1 = new TestThread2("https://i0.hdslb.com/bfs/article/735f7de46e0e891293c99323c5c4620c3ef117ae.jpg@1320w_2346h.webp","碧蓝航线1.jpg");TestThread2 t2 = new TestThread2("https://i0.hdslb.com/bfs/article/0cfe3289fb1ea4610477e81c03e788b403afeca1.jpg@1320w_1868h.webp","碧蓝航线2.jpg");TestThread2 t3 = new TestThread2("https://i0.hdslb.com/bfs/article/f94e072c0fd439ed340817813cd72fd8c5a2d804.png@1320w_2640h.webp","碧蓝航线3.jpg");t1.start();t2.start();t3.start();}
}//下载器
class WebDownloader{//下载方法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方法出现方法");}}
}
//创建线程方式2:实现runnable,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
public class TestThread3 implements Runnable{@Overridepublic void run() {//run()方法线程体for (int i = 0; i < 20; i++) {System.out.println("我在看代码————"+i);}}public static void main(String[] args) {//创建runnable接口的实现类对象TestThread3 testThread3 = new TestThread3();//创建一个线程对象
//        Thread thread = new Thread(testThread3);
//
//        thread.start();new Thread(testThread3).start();for (int i = 0; i < 20; i++) {System.out.println("我在学习多线程————"+i);}}
}
//练习Thread,实现多线程同步下载图片
public class TestThread2 extends Thread{private String url; //图片地址private String name; //保存文件名public TestThread2(String url,String name){this.url = url;this.name = name;}//下载图片线程的执行体@Overridepublic void run() {WebDownloader webDownloader = new WebDownloader();webDownloader.downloader(url,name);System.out.println("下载了文件名为:"+name);}public static void main(String[] args) {TestThread2 t1 = new TestThread2("https://i0.hdslb.com/bfs/article/735f7de46e0e891293c99323c5c4620c3ef117ae.jpg@1320w_2346h.webp","碧蓝航线1.jpg");TestThread2 t2 = new TestThread2("https://i0.hdslb.com/bfs/article/0cfe3289fb1ea4610477e81c03e788b403afeca1.jpg@1320w_1868h.webp","碧蓝航线2.jpg");TestThread2 t3 = new TestThread2("https://i0.hdslb.com/bfs/article/f94e072c0fd439ed340817813cd72fd8c5a2d804.png@1320w_2640h.webp","碧蓝航线3.jpg");new Thread(t1).start();new Thread(t2).start();new Thread(t3).start();}
}//下载器
class WebDownloader{//下载方法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方法出现方法");}}
}

4.初识并发现问题

  • 通过例子发现:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
//多个线程同时操作同一个对象
//买火车票的例子//通过例子发现:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
public class TestThread4 implements Runnable{//票数private int ticketNums = 10;@Overridepublic void run() {while(true){if (ticketNums<=0){break;}//模拟延时try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}//通过这个方法可以获得当前执行线程的名字System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"票");}}public static void main(String[] args) {TestThread4 ticket = new TestThread4();new Thread(ticket,"学生").start();new Thread(ticket,"老师").start();new Thread(ticket,"黄牛党").start();}
}

5.龟兔赛跑模拟

1.Runnable,使用run()

2.首先要有赛道距离

3.判断比赛胜利

4.判断比赛是否结束

5.龟兔赛跑开始

6.故事中兔子是睡觉的,模拟兔子睡觉

//模拟龟兔赛跑
public class Race implements Runnable{private static String winner;@Overridepublic void run() {//首先要有比赛距离for (int i = 0; i < 101; i++) {//模拟兔子睡觉if (Thread.currentThread().getName().equals("兔子")&&i%10==0){try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}//判断比赛是否结束boolean flag = GameOver(i);if (flag){break;}System.out.println(Thread.currentThread().getName()+"跑了"+i+"米");}}//判断比赛胜利private boolean GameOver(int steps){if (winner!=null){return true;}{if (steps>=100){winner = Thread.currentThread().getName();System.out.println("winner is"+winner);return true;}}return false;}public static void main(String[] args) {Race race = new Race();new Thread(race,"兔子").start();new Thread(race,"乌龟").start();}
}

6.Callable接口

  • 创建线程方式三:实现Callable接口,重写call方法
  • 创建执行服务: ExecutorService ser = Executors.newFixedThreadPool(1);
  • 提交执行:Future r1 = ser.submit(t1);
  • 获取结果:boolean rs1 = r1.get();
  • 关闭服务:ser.shutdownNow();
//创建线程方式三:实现callable接口
public class TestCallable implements Callable<Boolean> {private String url; //图片地址private String name; //保存文件名public TestCallable(String url,String name){this.url = url;this.name = name;}//下载图片线程的执行体@Overridepublic Boolean call() {WebDownloader webDownloader = new WebDownloader();webDownloader.downloader(url,name);System.out.println("下载了文件名为:"+name);return true;}public static void main(String[] args) throws ExecutionException, InterruptedException {TestCallable t1 = new TestCallable("https://i0.hdslb.com/bfs/article/735f7de46e0e891293c99323c5c4620c3ef117ae.jpg@1320w_2346h.webp","碧蓝航线1.jpg");TestCallable t2 = new TestCallable("https://i0.hdslb.com/bfs/article/0cfe3289fb1ea4610477e81c03e788b403afeca1.jpg@1320w_1868h.webp","碧蓝航线2.jpg");TestCallable t3 = new TestCallable("https://i0.hdslb.com/bfs/article/f94e072c0fd439ed340817813cd72fd8c5a2d804.png@1320w_2640h.webp","碧蓝航线3.jpg");//创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(3);//提交执行Future<Boolean> r1 = ser.submit(t1);Future<Boolean> r2 = ser.submit(t2);Future<Boolean> r3 = ser.submit(t3);//获取结果boolean rs1 = r1.get();boolean rs2 = r2.get();boolean rs3 = r3.get();//关闭服务ser.shutdownNow();}
}//下载器
class WebDownloader{//下载方法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方法出现方法");}}
}

7.静态代理模式

  • 代理模式:为其他对象提供一种代理以控制对这个对象的访问。说白了就是"真实对象"的代表,在访问对象时引入一定程度的间接性,因为这种间接性可以附加多种用途。
  • 好处:
    代理对象可以做很多真实对象做不了的事情
    真实对象专注做自己的事情
  • 首先,要定义一个接口;其次,定义一个用户类来实现接口;再其次,定义代理类
/*
静态代理模式总结;真实对象和代理对象都要实现同一接口代理对象要代理真实角色
好处:代理对象可以做很多真实对象做不了的事情真实对象专注做自己的事情*/
public class StaticProxy {public static void main(String[] args) {new Thread( ()-> System.out.println("愛してる") ).start();You you = new You();//你要结婚WeddingCompany weddingCompany = new WeddingCompany(new You());weddingCompany.HappyMarry();}
}//1.首先要定义一个接口
interface Marry{void HappyMarry();
}//2.定义一个用户类去实现这个接口
//真实角色,你去结婚
class You implements Marry{@Overridepublic void HappyMarry() {System.out.println("僕と、結婚しましょう");}
}//3.定义代理类
//婚姻公司,代理帮助结婚
class WeddingCompany implements Marry{//声明被代理对象-->>真实目标角色private Marry target;//创建构造方法public WeddingCompany(Marry target) {this.target = target;}//实现抽象方法@Overridepublic void HappyMarry() {before();this.target.HappyMarry();//这就是真实对象after();}private void after() {System.out.println("结婚后,收尾款");}private void before() {System.out.println("结婚前,布置现场");}
}

8.Lambda表达式

  • 为什么要使用Lambda:避免匿名内部类定义过多;可以让代码看起来简洁;去掉了一堆没有意义的代码,只留下核心逻辑
  • Functional Interface函数式接口:任何接口,有且仅有一个抽象方法,但可以有多个非抽象方法的接口
public interface Runnable{       //接口public abstract void run(); //抽象方法
}
  • 逐步简化

①实现类

public class TestLambda3 {public static void main(String[] args) {King king = new General();king.queen(1);}
}//首先定义一个接口
interface King{void queen(int a);
}//1.  实现类
class General implements King{@Overridepublic void queen(int a) {System.out.println("Obey  " + a);}
}

②静态内部类

public class TestLambda3 {//2.  静态内部类static class General2 implements King{@Overridepublic void queen(int a) {System.out.println("Obey  " + a);}}public static void main(String[] args) {King king = new General2();king.queen(2);}
}
interface King{void queen(int a);
}

③局部内部类

public class TestLambda3 {public static void main(String[] args) {//3. 局部内部类class General3 implements King{@Overridepublic void queen(int a) {System.out.println("Obey  " + a);}}King king = new General3();king.queen(3);}
}interface King{void queen(int a);
}

④匿名内部类

public class TestLambda3 {public static void main(String[] args) {//4. 匿名内部类King king = new King() {@Overridepublic void queen(int a) {System.out.println("Obey  " + a);}}; //king.queen(4);}
}interface King{void queen(int a);
}

⑤lambda表达式

public class TestLambda3 {public static void main(String[] args) {//5. lambda表达式King king = (int a) -> {System.out.println("Obey  " + a);};king.queen(5);}
}
interface King{void queen(int a);
}

⑥再简化

public class TestLambda3 {public static void main(String[] args) {//5. lambda表达式King king = (int a) -> {System.out.println("Obey  " + a);};//简化1:去掉参数类型king = (a) -> {System.out.println("Obey  " + a);};//简化2:简化括号king = a -> {System.out.println("Obey  " + a);};//简化3:去掉花括号king = a -> System.out.println("Obey  " + a);king.queen(5);}
}
interface King{void queen(int a);
}

⑥再简化总结:

​ 1.lambda表达式只能有一行代码的情况下,才能成为一行;如果有多行,那么使用代码块(即有花括号的)

​ 2.简化前提是接口为函数式接口

​ 3.多个参数也可以去掉参数类型,要去掉就都去掉,但必须要加上括号

Java多线程学习——01相关推荐

  1. Java多线程学习处理高并发问题

    在程序的应用程序中,用户或请求的数量达到一定数量,并且无法避免并发请求.由于对接口的每次调用都必须在返回时终止,因此,如果接口的业务相对复杂,则可能会有多个用户.调用接口时,该用户将冻结. 以下内容将 ...

  2. java多线程学习-java.util.concurrent详解

    http://janeky.iteye.com/category/124727 java多线程学习-java.util.concurrent详解(一) Latch/Barrier 博客分类: java ...

  3. Java多线程学习(二)synchronized关键字(1)

    转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...

  4. java多线程学习笔记。

    java多线程学习笔记 线程的优缺点: 多线程的好处: 充分利用多处理核心,提高资源的利用率和吞吐量. 提高接口的响应效率,异步系统工作. 线程的风险: 安全危险(竞争条件):什么坏事都没有发生.在没 ...

  5. 【转】Java 多线程学习

    原网址:https://www.cnblogs.com/yjd_hycf_space/p/7526608.html Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实J ...

  6. 转:Java多线程学习(总结很详细!!!)

    Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程 ...

  7. java线程学习,GitHub - zksir/thread: Java多线程学习

    Java多线程学习 threadcoreknowledge包----线程核心知识基础 createthreads包 创建线程 1.实现多线程的方法是1种还是2种还是4种? Oracle官方:2种,一种 ...

  8. Java多线程学习之路(四)---死锁(DeadLock)

    Java多线程学习之路(四)-死锁(DeadLock) 1.定义 死锁就是多个线程在竞争共享资源的时候,相互阻塞,不能脱身的状态(个人理解).其实死锁一定程度上可以看成一个死循环. 举个现实生活中的例 ...

  9. Java多线程学习 (超详细总结)

    Java多线程学习 一.概要 二. JAVA 线程实现/创建方式 2.1 继承Thread 类 2.2 实现 Runnable 接口 2.3 Thread和Runnable的区别 2.4 总结 三.线 ...

最新文章

  1. linux命令:groupadd
  2. 遍历——PowerShell三分钟(十)
  3. Go 语言编程 — Overview
  4. Mesos源码分析(8): Mesos-Slave的初始化
  5. html加上 extjs右键,extjs 处理HTML事件和自定义事件
  6. 个人认为不错的句子(part2)--计算机是一种工具,但是如果没有绝对精确的指令,计算机也将一无是处
  7. Sping Environment为Null的原因和解决方法
  8. Gitlab 服务器搭建,maven安装与jdk安装,linux下安装git
  9. spring扩展点四:SmartInitializingSingleton 补充
  10. 1222-周一开盘红红火火大涨的一天。EG,PVC,沪铜,国际铜,纯碱涨停
  11. 微信支付商户平台开通流程
  12. 对单位cps和单位kc的理解
  13. 2022年国内最牛的Java面试八股文合集(MCA版),不接受反驳
  14. 服务端开发基础知识点
  15. Python 爬虫实战:分析豆瓣中最新电影的影评
  16. java -g_Java G1深入理解(转)
  17. 恋词题源报刊Unit5背诵
  18. Rocket Typist Pro 2.1.2 中文特别版 Mac 增强型文本快速输入工具让你打字更快
  19. gdb 的用法(Linux调试器)
  20. 拆装计算机 教案,拆装计算机教案.pdf

热门文章

  1. 高斯-约当(Gauss-Jordan)消元法
  2. 高斯-约当消元法(转)
  3. 消息传递,生产者消费者
  4. BOL简单分析(一)
  5. 小技巧:如何创建公共邮箱?教育邮箱创建哪个好?
  6. 动漫推荐之恋爱随意链接
  7. win10系统怎么没有iis服务器,Win10企业版系统iis无法启动怎么解决?
  8. 微软发布命令行神器,文件误删秒恢复
  9. 『摄影知识』自然光的应用
  10. 波束成形算法之波束宽度