线程的核心概念

  • 线程就是独立的执行路径
  • 在程序运行时,即使没有自己创建线程,后台也会有多个线程,如main 线程,GC线程;
  • main()称之为主线程,为系统的入口,用于执行整个程序;
  • 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能认为的干预。
  • 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;
  • 线程会带来额外的开销,如CPU调度时间,并发控制开销。
  • 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

线程创建方式

Thread 方法

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

继承 Thread

//创建线程方式1 ,继承Thread ,重写 run 方法。调用start 开启先成功
public class TestThread01  extends Thread{@Overridepublic void run() {//线程的run 方法for (int i = 0; i < 200; i++) {System.out.println("TestThread01 run: " +i);}}
}

main方法测试

 public static void main(String[] args) {//main 线程 , 主线程//创建一个线程对象TestThread01 thread01 = new TestThread01();//调度一个start 方法开启线程// 会是交叉执行  不存在先后执行  是由cpu 决定执行的thread01.start();// 如果为run方法 和 从上到下执行没啥区别//thread01.run(); for (int i = 0; i < 2000; i++) {System.out.println("TestThread main : " +i);}}

可以查看执行结果 run 方法 和从上到下调用方法的结果一直,而 start 方法的执行结果则是交叉执行。

模拟多线程下载图片

导入 下载文件的工具类

    <dependencies><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency></dependencies>

具体实现代码

package com.mayb.demo01;import org.apache.commons.io.FileUtils;import java.io.File;
import java.io.IOException;
import java.net.URL;//练习Thread ,实现多线程同步下载图片
public class TestThread02 extends Thread{private String url; //网络文件路径private String name;//需要保存为什么文件名称public   TestThread02(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) {TestThread02 thread01 = new TestThread02("图片路径"  ,"1.jpg");TestThread02 thread02 = new TestThread02("图片路径"  ,"2.jpg");TestThread02 thread03 = new TestThread02("图片路径"  ,"3.jpg");TestThread02 thread04 = new TestThread02("图片路径"  ,"4.jpg");thread01.start();thread02.start();thread03.start();thread04.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 方法异常。");}}
}

总结

注意,线程在开启不一定立即执行,由cpu调度。

Runnable 方法

  • 定义 Runnable 类实现 Runnable 接口
  • 实现 run() 方法,编写线程执行体
  • 创建线程对象,调用 start() 方法启动线程
package com.mayb.demo01;//创建线程方式2,实现runnable接口, 重写run方法,执行线程需要丢入 runnable 接口实现类。调用start方法。
public class TestThread03 implements Runnable{public void run() {//线程的run 方法for (int i = 0; i < 200; i++) {System.out.println("TestThread03 run: " +i);}}public static void main(String[] args) {//main 线程 , 主线程//创建 Runnable 接口的实现对象TestThread03 thread03 = new TestThread03();//创建线程对象 通过线程对象来开启我们的线程 (代理)new Thread(thread03).start();for (int i = 0; i < 2000; i++) {System.out.println("TestThread main : " +i);}}
}

加强练习

龟兔赛跑的案例

  1. 首先来个赛道距离,然后要离终点越来越近
  2. 判断比赛是否结束
  3. 打印出胜利者
  4. 龟兔赛跑开始
  5. 故事中是乌龟赢的,兔子需要睡觉,所以我们来模拟兔子睡觉
  6. 终于,乌龟赢得比赛
//模拟龟兔赛跑
public class ARun  implements Runnable{//胜利者private static  String winner;public void run() {for (int i = 0; i <= 100; i++) {//模拟兔子休息 每跑10 步就休息200 msif (Thread.currentThread().getName().equals("兔子") && i%10 == 0){try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}}//判断比赛是否结束boolean flag = gameOver(i);// 如果为 true 就结束比赛if (flag){break;}System.out.println(Thread.currentThread().getName()+"--->跑了"+ i + "米");}}//判断是否已经结束比赛public boolean gameOver(int steps){//判断是否有胜利者if (winner != null){//已经存在胜利者return false;}else {if (steps >= 100){winner = Thread.currentThread().getName();System.out.println("winner is " + winner );return  true;}}return false;}//Testpublic static void main(String[] args) {ARun aRun = new ARun();new Thread(aRun,"兔子").start();new Thread(aRun,"乌龟").start();}
}

Callable 方法

1.实现Callable接口,需要返回值类型
2.重写call方法, 需要抛出异常
3.创建目标对象
4.创建执行服务: ExecutorService ser = Executors.newFixedThreadPool(1);
5.提交执行: Future result1 = ser.submit(t1);
6.获取结果: boolean r1 = result1.get()
7.关闭服务: ser.shutdownNow();

用 Callable 接口改造下载图片案例

import org.apache.commons.io.FileUtils;import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;//创建线程3 实现Callable 接口
/*
callable 的好处
1、可以定义返回值
2、可以抛出异常*/
public class TestCallable implements Callable<Boolean> {private String url; //网络文件路径private String name;// 需要保存为什么文件名称public   TestCallable(String url,String name){this.url = url;this.name = name;}public 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 {TestThread02 thread01 = new TestThread02("图片路径"  ,"1.jpg");TestThread02 thread02 = new TestThread02("图片路径"  ,"2.jpg");TestThread02 thread03 = new TestThread02("图片路径"  ,"3.jpg");//创建执行服务:  3 条线程ExecutorService ser = Executors.newFixedThreadPool(3);//提交执行:Future<Boolean> result1 = ser.submit(thread01);Future<Boolean> result2 = ser.submit(thread02);Future<Boolean> result3 = ser.submit(thread03);//获取结果: 就是call 方法 返回的值boolean r1 = result1.get();boolean r2= result2.get();boolean r3 = result3.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 方法异常。");}}
}

多线程 - 三种实现相关推荐

  1. 多线程 三种创建方式及区别

    线程概念 进程:启动一个程序就是一个进程. 线程:在一个程序里面,多个事情同步进行,这个事情是由线程来完成 不使用多线程的效果 如果我们不使用线程,会怎么样呢?看下面代码 新建立一个hero类包含英雄 ...

  2. 多线程三种同步方式(模拟银行取款)

    方法一:同步代码块 Accoun package com.bjsxt.synch1;/*** 银行账户类*/ public class Account {private int balance = 6 ...

  3. java线程初始方法三种_Java 多线程 三种实现方式

    Java多线程实现方式主要有三种:继承Thread类.实现Runnable接 口.使用ExecutorService.Callable 实现有返回结果的多线程.其中前两种方式线程执行完后都没有返回值, ...

  4. 多线程三种设计模式-

    Future.Master-Worker和生产者-消费者模型 2018年03月06日 22:32:08 努力做最好的自己 阅读数:391 并行设计模式属于设计优化的一部分,它是对一些常用的多线程结构的 ...

  5. java多线程w3c_Java创建多线程的三种方式

    前言 这篇文章主要讲述线程的概念.组成.Java创建多线程的三种方式以及线程的类型. 线程概念 线程和进程的区别 **进程:**正在运行的程序,例如:你打开 的qq音乐.exe程序,其由PCB(进程控 ...

  6. java多线程实现表复制_Java多线程的三种实现方式

    今天简单说一下Java三种多线程实现方式和区别,主要有实现Runnable.Callable和继承Thread三种方式. 实现Runnable的方式 这种方式比较常用,当我们的线程类有继承其他的类的情 ...

  7. ios多线程开发的常用三种方式

    ios多线程开发的常用三种方式 1.NSThread 2.NSOperationQueue 3.GCD NSThread: 创建方式主要有两种: [NSThread detachNewThreadSe ...

  8. oracle数据库开多线程,学习笔记:Oracle表数据导入 DBA常用单线程插入 多线程插入 sql loader三种表数据导入案例...

    天萃荷净 oracle之数据导入,汇总开发DBA在向表中导入大量数据的案例,如:单线程向数据库中插入数据,多线程向数据表中插入数据,使用sql loader数据表中导入数据案例 1.Oracle数据库 ...

  9. 多线程—Thread类及线程三种创建方式及对比

    线程创建的3种方法: 1.继承Thread类并重写run方法 Thread类方法: Thread Thread.currentThread() :获得当前线程的引用.获得当前线程后对其进行操作. Th ...

最新文章

  1. Tomcat内存溢出解决方案
  2. 在CSS3中,可以利用transform功能来实现文字或图像的旋转、缩放、倾斜、移动这四种类型的变形处理...
  3. Java 源码学习系列(三)——Integer
  4. input 不显示边框_不需要使用JavaScript
  5. ClickHouse设置用户名密码
  6. Doing Homework HDU - 1074
  7. kryoserializer java_使用Kryo序列化任意Java对象(获取IllegalAccess...
  8. C++优先队列priority_queue详解
  9. 华为如何造车?动机、底气、战略布局、客户
  10. python图片马赛克_Python实现PS滤镜中马赛克效果示例
  11. 拓端tecdat|R语言再保险合同定价案例研究
  12. 从RTS游戏看游戏开发-2
  13. 硬件基础知识-二极管基础
  14. mac换硬盘重装系统记录
  15. MeGUI 压片之新手上路
  16. windows启动时自动运行程序四种方法(登录或不登录都可以的)
  17. 3D打印牛排,入口即化!你敢吃吗?
  18. 报错GENERIC_INTERNAL_ERROR(65536)处理
  19. [ 高斯消元 二分图最大匹配 ] [ HEOI2013 ] BZOJ3168 钙铁锌硒维生素
  20. texture中的 anisotropy属性,纹理的各向异性

热门文章

  1. 科技企业捐赠武汉最新最全排名(截止2月13日)
  2. 为什么lol计算机内存不足怎么办,win7玩LOL英雄联盟提示“内存不足”怎么处理?(图文)...
  3. android 桥接,路由器一键桥接Android实现
  4. 源享科技为什么关闭了_关闭这个阀门竟然需要转8000圈?
  5. 伞源科技Pinpoint和sonarQube对比
  6. 2022/06/14,15 day15与day16:内部类
  7. [计算机网络] CSMA/CD 协议限定数据帧最小长度为 64B 不变,根据给定的数据传输速率计算得到争用期长度
  8. java并发原理实战(8)-- lock接口使用和认识
  9. unity接入quick sdk报错总结(Andriod第二版)
  10. 数据结构与算法—堆(heap)