1、我的第一个多线程程序

方法一: extends Thread

package cn.hanquan.test;public class StartThread extends Thread {@Overridepublic void run() {// 线程入口点for (int i = 0; i < 2000; i++) {System.out.println("偷偷敲代码");}}public static void main(String[] args) {/** 启动线程* 1、创建子类对象* 2、调用子类对象的start方法*/StartThread st=new StartThread();st.start();for (int i = 0; i < 2000; i++) {System.out.println("吃饭");}}
}



方法二:implements Runnable(推荐)

package cn.hanquan.test;public class StartRun implements Runnable {// 线程入口点@Overridepublic void run() {for (int i = 0; i < 1000; i++)System.out.println("偷偷敲代码");}public static void main(String[] args) {// 创建实现类对象StartRun sr = new StartRun();// 创建代理类对象Thread t = new Thread(sr);// 启动t.start();// 三合一:如果一个对象只是用一次,我们可以使用匿名// new Thread(new StartRun()).start();for (int i = 0; i < 1000; i++)System.out.println("我在吃饭");}
}

方法三:implements Callable(了解)

功能:多线程下载网页图片

package cn.hanquan.test;import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;import org.apache.commons.io.FileUtils;public class TDownloader implements Callable<Boolean> {private String url;private String name;// 构造器public TDownloader(String url, String name) {this.url = url;this.name = name;}// 线程入口点@Overridepublic Boolean call() {WebDownloader.download(url, name);System.out.println("success");return true;}public static void main(String[] args) throws InterruptedException, ExecutionException {TDownloader cd1 = new TDownloader("https://img-blog.csdnimg.cn/20190724224219516.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NpbmF0XzQyNDgzMzQx,size_16,color_FFFFFF,t_70","1.png");TDownloader cd2 = new TDownloader("https://www.bjsxt.com/wp-content/themes/sxt/statics/images/bjsxt/images/share/project2.png", "2.png");TDownloader cd3 = new TDownloader("https://img-blog.csdnimg.cn/20190722092922681.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NpbmF0XzQyNDgzMzQx,size_16,color_FFFFFF,t_70","3.png");// 创建执行服务ExecutorService ser = Executors.newFixedThreadPool(3);// 提交执行Future<Boolean> result1 = ser.submit(cd1);Future<Boolean> result2 = ser.submit(cd2);Future<Boolean> result3 = ser.submit(cd3);// 获取结果boolean r1 = result1.get();boolean r2 = result2.get();boolean r3 = result3.get();// 关闭服务ser.shutdownNow();}
}//下载工具
class WebDownloader {public static void download(String url, String name) {try {FileUtils.copyURLToFile(new URL(url), new File(name));} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

运行结果:可以看到,图片成功被下载


2、多线程下载图片

需要使用commons.io

package cn.hanquan.test;import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;import org.apache.commons.io.FileUtils;public class TDownloader extends Thread {private String url;private String name;// 构造器public TDownloader(String url, String name) {this.url = url;this.name = name;}// 线程入口点@Overridepublic void run() {WebDownloader.download(url, name);System.out.println("success");}public static void main(String[] args) {TDownloader t1 = new TDownloader("https://img-blog.csdnimg.cn/20190724224219516.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NpbmF0XzQyNDgzMzQx,size_16,color_FFFFFF,t_70","1.png");TDownloader t2 = new TDownloader("https://www.bjsxt.com/wp-content/themes/sxt/statics/images/bjsxt/images/share/project2.png", "2.png");TDownloader t3 = new TDownloader("https://img-blog.csdnimg.cn/20190722092922681.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NpbmF0XzQyNDgzMzQx,size_16,color_FFFFFF,t_70","3.png");t1.start();t2.start();t3.start();}
}//下载工具
class WebDownloader {public static void download(String url, String name) {try {FileUtils.copyURLToFile(new URL(url), new File(name));} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

3.使用多线程模拟抢票

出现重复数字的原因是:线程不安全

package cn.hanquan.test;public class StartRun implements Runnable {public static int ticket = 100;// 线程入口点@Overridepublic void run() {while (ticket > 0) {//ticket--;System.out.println(Thread.currentThread().getName() + "->" + ticket--);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {// 三合一:如果一个对象只是用一次,我们可以使用匿名new Thread(new StartRun(), "小红").start();new Thread(new StartRun(), "魔鬼").start();new Thread(new StartRun(), "布谷鸟").start();}
}

部分结果

【Java多线程】创建多线程的三种方式相关推荐

  1. Java中创建线程的三种方式

    Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)继承Thread类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. ...

  2. java 多线程编程(包括创建线程的三种方式、线程的生命周期、线程的调度策略、线程同步、线程通信、线程池、死锁等)

    1 多线程的基础知识 1.1 单核CPU和多核CPU 单核CPU,其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程的任务.微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那 ...

  3. java 创建线程_【80期】说出Java创建线程的三种方式及对比

    点击上方"Java面试题精选",关注公众号 面试刷图,查缺补漏 >>号外:往期面试题,10篇为一个单位归置到本公众号菜单栏->面试题,有需要的欢迎翻阅. 一.Ja ...

  4. Java 创建线程的三种方式

    一.继承Thread类创建 1.定义一个类继承Thread类,并重写Thread类的run()方法,run()方法的方法体就是线程要完成的任务,因此把run()称为线程的执行体: 2.创建该类的实例对 ...

  5. Java创建线程的三种方式

    一.继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. (2)创建Thread子类的实 ...

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

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

  7. java的如何创建js_[Java教程]JS创建事件的三种方式(实例)

    [Java教程]JS创建事件的三种方式(实例) 0 2016-05-11 14:00:16 1.普通的定义方式 οnclick="Sfont=prompt('请在文本框中输入红色','红色' ...

  8. java bean 工厂模式_Spring框架通过工厂创建Bean的三种方式实现

    工厂模式 Spring中bean的创建,默认是框架利用反射new出来的bean实例.有时候也会有一些复杂的情况. 假设有一个飞机,属性如下,现在需要造很多同型号的飞机,那么唯一需要改变的属性只有Dri ...

  9. java 创建数组的三种方式及区别

    创建数组的三种方式:其实分为2类,一种是静态的创建,如方式一.一种是动态的创建,只不过根据写法的不同分为方式二和方式三: // 数组初始化的三种方式//1.声明,分配空间并赋值int[] arr0 = ...

  10. 把对象的创建交给spring来管理——  1.创建bean的三种方式     2.bean对象的作用范围     3.bean对象的生命周期

    把对象的创建交给spring来管理 spring对bean的管理细节     1.创建bean的三种方式     2.bean对象的作用范围     3.bean对象的生命周期 创建Bean的三种方式 ...

最新文章

  1. C++ 不能在构造函数中调用构造函数
  2. 有趣的HTML5/CSS3艺术网站
  3. linux搭建vsftp服务器_Linux配置VSFTP服务器的方法
  4. 马斯克回应一切:2018年极其痛苦,福特难熬下次经济衰退,后悔发太多推特
  5. git stash暂存命令
  6. 让华泰浮盈10亿美金的AssetMark-统包资产管理平台价值几何?
  7. picasa csdn_前5名:Picasa的开源替代品,SourceForge / Slashdot采访等
  8. 《第一桶金怎么赚——淘宝开店创业致富一册通》一一1.2 创业者应具备的条件与经验...
  9. 【GreenDao学习笔记】SQLite数据库保存float/double小数类型精度丢失
  10. rocketmq 消息删除_RocketMq Topic创建和删除
  11. 8月第4周基金排行榜 | TokenInsight
  12. 计算机图形学VC 配置,计算机图形学(VC++实现)(第2版)
  13. 尤雨溪:Vue3即将成为新的默认版本!
  14. java中使用Calendar日期类获得下一个月有多少天
  15. C#Unity3d怪物在一定范围内巡逻发现玩家自动跟踪攻击,血量低于30%自动向后跳3米并缓慢回血的代码和使用
  16. c++内存管理:new与delete,深拷贝与浅拷贝
  17. 计算机课的底纹在哪,2017计算机二级MSOffice考试边框与底纹的设置
  18. 【按键精灵】幻想手游排行榜踩空间
  19. 简述余弦函数cos(x)和反余弦函数acos(x)------(附Demo案例)
  20. java的下拉框的设置默认值,html下拉选项属性 html下拉框怎么设置默认值?

热门文章

  1. FairMOT实时多目标跟踪
  2. Kafka设计解析(三) : Kafka High Availability (下)
  3. (三)Boost库之字符串处理
  4. Instsrv.exe可以给系统安装和删除服务
  5. 关于模板函数/模板类编译成DLL
  6. Kafka参数broker.id详解
  7. ActiveMQ简述
  8. 读者吐槽:Go 面试总被问到 RPC
  9. OS- -I/O之I/O设备
  10. 数据结构--图(Graph)详解(三)