热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:多线程:多线程的应用(网图下载模拟售票龟兔赛跑)

本文由编程笔记#小编为大家整理,主要介绍了多线程:多线程的应用(网图下载模拟售票龟兔赛跑)相关的知识,希望对你有一定的参考价值。1、网图下载(继承Thread类)
本文由编程笔记#小编为大家整理,主要介绍了多线程:多线程的应用(网图下载模拟售票龟兔赛跑)相关的知识,希望对你有一定的参考价值。


1、网图下载(继承Thread类)

(1)导包

技术图片

 

(2)创建WebDownloader 类,书写下载图片的方法:


public class WebDownloader {
public void downloader(String url,String name){
try {
FileUtils.copyURLToFile(
new URL(url),new File(name));
}
catch (IOException e) {
e.printStackTrace();
}
}
}

(3)创建TestThread 类,继承Thread类,用于实现多线程:


public class TestThread extends Thread{
private String url;//网络图片地址
private String name;//保存的文件名
public TestThread(String url, String name) {
this.url = url;
this.name = name;
}
public void run(){
WebDownloader webDownloader
=new WebDownloader();
webDownloader.downloader(url,name);
System.out.println(
"下载了:"+name);
}
public static void main(String[] args) {
TestThread testThread1
=new TestThread("https://img2018.cnblogs.com/blog/1392562/201908/1392562-20190817173332328-1651495806.png","1.pnj");
TestThread testThread2
=new TestThread("https://img2020.cnblogs.com/blog/1392562/202005/1392562-20200516214429116-874432537.png","2.png");
TestThread testThread3
=new TestThread("https://img2018.cnblogs.com/blog/1392562/201908/1392562-20190817173332328-1651495806.png","3.png");
testThread1.start();
testThread2.start();
testThread3.start();
}
}

继承Thread类,书写run方法,在该方法内部调用图片下载的方法,最后,创建线程对象,并利用对象调用start方法开启三个线程

(4)测试:


下载了:2.png
下载了:
1.pnj
下载了:
3.png

技术图片

 

2、模拟售票

(1)代码:


public class TestThread implements Runnable{
private int ticketsNums=10;
@Override
public void run() {
while(true){
if(ticketsNums<=0){
break;
}
try {
Thread.sleep(
200);//延时200ms
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread()
+"拿到了"+ticketsNums--+"张票");
}
}
public static void main(String[] args) {
TestThread testThread
=new TestThread();
new Thread(testThread,"zhai").start();
new Thread(testThread,"zhang").start();
new Thread(testThread,"liu").start();
}
}

调用sleep方法的目的是避免第一个线程长时间的占用,给后面两个线程机会

(2)测试:


Thread[liu,5,main]拿到了10张票
Thread[zhang,
5,main]拿到了9张票
Thread[zhai,
5,main]拿到了8张票
Thread[liu,
5,main]拿到了7张票
Thread[zhang,
5,main]拿到了6张票
Thread[zhai,
5,main]拿到了5张票
Thread[liu,
5,main]拿到了4张票
Thread[zhang,
5,main]拿到了3张票
Thread[zhai,
5,main]拿到了2张票
Thread[zhang,
5,main]拿到了1张票
Thread[liu,
5,main]拿到了1张票
Thread[zhai,
5,main]拿到了0张票

可以看到有的票出现了两次,这是因为在多个线程共享同一个数据的时候存在线程安全的问题,当对存在安全隐患的数据加锁后,会导致程序的性能降低,所以,如果是多个线程操作同一个数据,一定要选择线程安全的方法,如果不是,可以选择线程不安全的方式来处理问题(多线程(线程间的数据共享、线程安全、线程通信)

 

3、龟兔赛跑

(1)代码:


public class Race implements Runnable {
//胜利者
private static String winner;
@Override
public void run() {
for(int i=0;i<=100;i++){
//模拟兔子休息
if(Thread.currentThread().getName().equals("兔子")&&i%20==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();
}
}

(2)测试:


乌龟跑了0步
乌龟跑了1步
乌龟跑了2步
乌龟跑了3步
乌龟跑了4步
乌龟跑了5步
乌龟跑了6步
乌龟跑了7步
乌龟跑了8步
乌龟跑了9步
乌龟跑了10步
乌龟跑了11步
乌龟跑了12步
乌龟跑了13步
乌龟跑了14步
乌龟跑了15步
乌龟跑了16步
乌龟跑了17步
乌龟跑了18步
乌龟跑了19步
乌龟跑了20步
乌龟跑了21步
乌龟跑了22步
乌龟跑了23步
乌龟跑了24步
乌龟跑了25步
乌龟跑了26步
乌龟跑了27步
乌龟跑了28步
乌龟跑了29步
乌龟跑了30步
乌龟跑了31步
乌龟跑了32步
乌龟跑了33步
乌龟跑了34步
乌龟跑了35步
乌龟跑了36步
乌龟跑了37步
乌龟跑了38步
乌龟跑了39步
乌龟跑了40步
乌龟跑了41步
乌龟跑了42步
乌龟跑了43步
乌龟跑了44步
乌龟跑了45步
乌龟跑了46步
乌龟跑了47步
乌龟跑了48步
乌龟跑了49步
乌龟跑了50步
乌龟跑了51步
乌龟跑了52步
乌龟跑了53步
乌龟跑了54步
乌龟跑了55步
乌龟跑了56步
乌龟跑了57步
乌龟跑了58步
乌龟跑了59步
乌龟跑了60步
兔子跑了0步
兔子跑了1步
兔子跑了2步
兔子跑了3步
兔子跑了4步
兔子跑了5步
兔子跑了6步
兔子跑了7步
兔子跑了8步
兔子跑了9步
兔子跑了10步
兔子跑了11步
兔子跑了12步
兔子跑了13步
兔子跑了14步
兔子跑了15步
兔子跑了16步
兔子跑了17步
兔子跑了18步
兔子跑了19步
乌龟跑了61步
乌龟跑了62步
乌龟跑了63步
乌龟跑了64步
乌龟跑了65步
乌龟跑了66步
乌龟跑了67步
乌龟跑了68步
乌龟跑了69步
兔子跑了20步
兔子跑了21步
兔子跑了22步
兔子跑了23步
兔子跑了24步
兔子跑了25步
兔子跑了26步
兔子跑了27步
兔子跑了28步
兔子跑了29步
兔子跑了30步
兔子跑了31步
兔子跑了32步
兔子跑了33步
兔子跑了34步
兔子跑了35步
兔子跑了36步
兔子跑了37步
兔子跑了38步
兔子跑了39步
乌龟跑了70步
乌龟跑了71步
乌龟跑了72步
乌龟跑了73步
乌龟跑了74步
乌龟跑了75步
乌龟跑了76步
乌龟跑了77步
乌龟跑了78步
乌龟跑了79步
乌龟跑了80步
乌龟跑了81步
乌龟跑了82步
乌龟跑了83步
乌龟跑了84步
乌龟跑了85步
乌龟跑了86步
乌龟跑了87步
乌龟跑了88步
乌龟跑了89步
乌龟跑了90步
乌龟跑了91步
乌龟跑了92步
乌龟跑了93步
乌龟跑了94步
乌龟跑了95步
乌龟跑了96步
乌龟跑了97步
乌龟跑了98步
乌龟跑了99步
winner is乌龟

此例子中,兔子线程和乌龟线程没有共享数据,也就是说他们的步数是相互独立的。当执行兔子线程的时候调用sleep方法,给乌龟线程更多的时间。率先执行到100步的时候程序停止,获取线程的名字。

 


推荐阅读
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 本文探讨了在Java多线程环境下,如何确保具有相同key值的线程能够互斥执行并按顺序输出结果。通过优化代码结构和使用线程安全的数据结构,我们解决了线程同步问题,并实现了预期的并发行为。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 本文将深入探讨如何在不依赖第三方库的情况下,使用 React 处理表单输入和验证。我们将介绍一种高效且灵活的方法,涵盖表单提交、输入验证及错误处理等关键功能。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 本文介绍如何在现有网络中部署基于Linux系统的透明防火墙(网桥模式),以实现灵活的时间段控制、流量限制等功能。通过详细的步骤和配置说明,确保内部网络的安全性和稳定性。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 本文探讨了在UC浏览器中调用分享面板后,图片无法正常显示的问题,并提供了详细的解决方法和代码示例。 ... [详细]
  • 本文详细介绍了在企业级项目中如何优化 Webpack 配置,特别是在 React 移动端项目中的最佳实践。涵盖资源压缩、代码分割、构建范围缩小、缓存机制以及性能优化等多个方面。 ... [详细]
  • FinOps 与 Serverless 的结合:破解云成本难题
    本文探讨了如何通过 FinOps 实践优化 Serverless 应用的成本管理,提出了首个 Serverless 函数总成本估计模型,并分享了多种有效的成本优化策略。 ... [详细]
  • 本文探讨了2012年4月期间,淘宝在技术架构上的关键数据和发展历程。涵盖了从早期PHP到Java的转型,以及在分布式计算、存储和网络流量管理方面的创新。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 解决FCKeditor应用主题后上传问题及优化配置
    本文介绍了在Freetextbox收费后选择FCKeditor作为替代方案时遇到的上传问题及其解决方案。通过调整配置文件和调试工具,最终解决了上传失败的问题,并对相关配置进行了优化。 ... [详细]
  • 装饰器是一种用于在不修改原函数代码的情况下,动态地添加功能的工具。它允许你在函数执行前后插入额外的逻辑,从而增强或改变函数的行为。 ... [详细]
author-avatar
手机用户2502930273
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有