一.java多线程基本概念

调用run():在主线程调用子线程的run()方法会中断主线程等到子线程执行完毕之后再执行主线程。

调用start():在主线程中执行子线程的start()后会与主线程同步执行。

二.线程创建的三种方法

Thread、Runnable、Callable

1.Thread入门

步骤:

  • 继承Thread类
  • 重写run方法
  • 调用start开启线程
 //创建线程方式一步骤:继承Thread类,重写run方法,调用start开启线程
public class test01 extends Thread{ @Override
public void run() {
for (int i = 0; i < 10;i++){
System.out.println("run方法执行..." + i);
}
} public static void main(String[] args) { //创建线程对象
test01 t1 = new test01(); //开启线程
t1.start(); for (int i = 0; i < 1000; i++){
System.out.println("main方法执行..." + i);
}
}
}

执行结果:交替执行

练习:使用Thread实现多线程同步下载图片

(1).导入依赖的jar包:

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

(2).编写test02.java:

 /**
* 使用多线程下载图片
* @author USTC_WZH
* @create 2019-12-05 11:26
*/
public class test02 extends Thread { //图片url地址
private String url;
//保存的文件名
private String name; public test02(String url, String name) {
this.url = url;
this.name = name;
} @Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url, name);
System.out.println("下载文件名:" + name);
} public static void main(String[] args) {
test02 t1 = new test02("http://lswhw.ustc.edu.cn/upload/20150427/20150427102635.jpg", "images/图片1.jpg");
test02 t2 = new test02("http://lswhw.ustc.edu.cn/upload/20150427/20150427103657.jpg", "images/图片2.jpg");
test02 t3 = new test02("http://lswhw.ustc.edu.cn/upload/20150427/20150427103010.jpg", "images/图片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("downloader方法出现异常");
}
}
}

2.实现Runable接口(重点使用)

三个步骤:

  • 实现Runnable接口,重写run方法
  • 执行线程需要丢入Runnable接口的实现类
  • 调用start方法

 /**
* 创建线程方法二步骤:
* 1.实现Runnable接口,重写run方法。
* 2.执行线程需要丢入runnable接口的实现类。
* 3.调用start方法。
* @author USTC_WZH
* @create 2019-12-05 14:14
*/
public class test03 implements Runnable{ @Override
public void run() {
for (int i = 0; i < 10;i++){
System.out.println("run方法执行..." + i);
}
} public static void main(String[] args) { //创建runnable接口的实现类对象
test01 t1 = new test01(); //创建线程对象,通过线程对象来开启我们的线程,代理模式
new Thread(t1).start(); for (int i = 0; i < 1000; i++){
System.out.println("main方法执行..." + i);
}
}
}

补充:模拟并发问题

 /**
* 模拟买火车票
*
* @author USTC_WZH
* @create 2019-12-05 14:32
*/
public class testerror implements Runnable { //火车票个数
private int ticketNums = 10; @Override
public void run() { while (true) { if (ticketNums <= 0) {
break;
} //模拟延时
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(Thread.currentThread().getName() + "-->拿了第" + ticketNums-- + "票");
}
} public static void main(String[] args) { testerror t = new testerror(); new Thread(t, "小明").start();
new Thread(t, "小红").start();
new Thread(t, "花花").start();
}
}

当同一个对象被多个线程访问时出现的并发错误的问题!

3.实现Callable接口(了解)

步骤:7步

  • 实现Callable接口,需要返回值类型
  • 重写call方法,需要抛出异常
  • 创建目标对象
  • 创建执行服务
  • 提交执行
  • 获取结果
  • 关闭服务
 package ustc.wzh.callable;

 import org.apache.commons.io.FileUtils;

 import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*; /**
* @author USTC_WZH
* @create 2019-12-05 14:44
* <p>
* 创建线程方式三步骤:
* 1.实现Callable接口,需要返回值类型
* 2.重写call方法,需要抛出异常
* 3.创建目标对象
* 4.创建执行服务
* 5.提交执行
* 6.获取结果
* 7.关闭服务
*/
//1.实现Callable接口
public class testCallable implements Callable<Boolean> { //图片url地址
private String url;
//保存的文件名
private String name; public testCallable(String url, String name) {
this.url = url;
this.name = name;
} //2.重写call方法
@Override
public Boolean call() throws Exception {
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("http://lswhw.ustc.edu.cn/upload/20150427/20150427102635.jpg", "images/图片1.jpg");
testCallable t2 = new testCallable("http://lswhw.ustc.edu.cn/upload/20150427/20150427103657.jpg", "images/图片2.jpg");
testCallable t3 = new testCallable("http://lswhw.ustc.edu.cn/upload/20150427/20150427103010.jpg", "images/图片3.jpg"); //4.创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3); //5.提交执行
Future<Boolean> r1 = ser.submit(t1);
Future<Boolean> r2 = ser.submit(t2);
Future<Boolean> r3 = ser.submit(t3); //6.获取结果
boolean rs1 = r1.get();
boolean rs2 = r2.get();
boolean rs3 = r3.get(); System.out.println("rs1=" + rs1 + ",rs2=" + rs2 + ",rs3=" + rs3); //7.关闭服务
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("downloader方法出现异常");
}
}
}

java的多线程之入门的更多相关文章

  1. Java的多线程 简单入门

    Java的多线程 简单入门 首先能够先搞清楚什么是程序.进程.线程,以及它们之间的关系: 定义: 一 程序仅仅是一组指令的有序集合.它是静态的 二 进程是具有一定独立功能的程序关于某个数据集合上的一次 ...

  2. Java 高级 --- 多线程快速入门

    这世上有三样东西是别人抢不走的:一是吃进胃里的食物,二是藏在心中的梦想,三是读进大脑的书 多线程快速入门 1.线程与进程区别 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.线程是一组 ...

  3. 【java】-- 多线程快速入门

    1.什么是进程?什么是线程?两者区别? 1.每个正在系统上运行的程序都是一个进程,每个进程包含一到多个线程,多线程处理就是允许一个进程中在同一时刻执行多个任务. 2.线程是一组指令的集合,或者是程序的 ...

  4. 微博,and java 多线程编程 入门到精通 将cpu 的那个 张振华

    http://down.51cto.com/data/2263476  java 多线程编程 入门到精通  将cpu 的那个 张振华 多个用户可以同时用一个 vhost,但是vhost之间是隔离的. ...

  5. java 多线程 快速入门

    ------------恢复内容开始------------ java 多线程 快速入门 1. 进程和线程 什么是进程? 进程是正在运行的程序它是线程的集合 进程中一定有一个主线程 一个操作系统可以有 ...

  6. 【Java】多线程入门

    Java多线程学习(入门) 前言 目前对于线程的了解仅仅停留在学习python的threading库,很多线程的概念没有真正弄清楚,所以选择来系统性的学习多线程.那么这次选择的是Java的多线程学习, ...

  7. Java程序员快速入门Go语言

    这篇文章帮助Java程序员快速入门Go语言. 转载至 开源中国社区. http://www.oschina.net 本文将以一个有代表性的例子为开始,以此让Java程序员对Go语言有个初步认识,随后将 ...

  8. Java工程师学习指南 入门篇

    Java工程师学习指南 入门篇 最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好.原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我之前写的文章都 ...

  9. Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

随机推荐

  1. Linux中最大进程数和最大文件数

    前言 Linux系统中可以设置关于资源的使用限制,比如:进程数量,文件句柄数,连接数等等. 在日常的工作中应该遇到过: -bash: fork: retry: Resource temporarily ...

  2. servlet规范--Servlet 规范其实就是对 HTTP 协议做面向对象的封装

    Servlet规范 一个最基本的 Java Web 项目所需的 jar 包只需要一个 servlet-api.jar ,这个 jar 包中的类大部分都是接口,还有一些工具类,共有 2 个包,分别是 j ...

  3. 近3年常考的Spring面试题及答案

    1. 一般问题 1.1. 不同版本的 Spring Framework 有哪些主要功能? Version Feature Spring 2.5 发布于 2007 年.这是第一个支持注解的版本. Spr ...

  4. mysql提示The server quit without updating PID file /usr/local/mysql/data/localhost.localdomain.pid

    chown -R mysql:mysql /var/lib/mysql 解决方法 :给予权限,执行 “chown -R mysql:mysql /var/lib/mysql” “chmod -R 75 ...

  5. 前端不缓存,ajax不缓存,js操作cookie

    今天实现网站注销功能时,需要清除cookie缓存,开始在网上搜索的是“js清除缓存”,发现很多都是预先防患缓存存储的内容,千篇一律,不过也学习到了:后来换成"js清除cookie" ...

  6. [08001] Could not create connection to database server. Attempted reconnect 3 times. Giving up IDEA2019的database插件无法链接mysql的解决办法(08001错误)

    [08001] Could not create connection to database server. Attempted reconnect 3 times. Giving up. 点击这里 ...

  7. js中函数的参数为函数的情况即回调函数

    js中函数的参数可以是数组对象也可以是函数,当参数为函数时我们叫做回调函数 //定义回调函数function B() { console.log("函数B")setTimeout( ...

  8. tomcat启动Publishing failed with multiple errors

    转自:https://blog.csdn.net/leisurelen/article/details/46940441 新安装一个tomcat插件.启动的时候就弹错误框.但tomcat还能使用. P ...

  9. linux-ifconfig 查看没有IP

    ifconfig 查看没有IP,如图: 解决方法: 1.切换路径到 2.进入编辑ifcfg-ens33文件(文件名可能不同)模式 3.ONBOOT改为yes 4.点击ESC,输入:wq进行保存 5.输 ...

  10. mysql 的逻辑架构 与 存储引擎的介绍

    mysql 的逻辑架构分为三层: 最上层的服务大多数基于网络的客户端.服务器的工具或者服务都有类似的架构,比如连接处理,授权认证.安全等 第二层架构:mysql的核心服务功能都在这一层,包括查询解析, ...