多线程调用同一个对象的方法_多线程之如何创建和使用线程

e5a152ebb9d6fbde7f7eea0373ff640d.png

一、创建线程和使用线程方式

1.1 继承Thread

让线程类继承自Thread类,然后重写run(),把需要多线程调用的代码放到run()中。但是需要开启线程的时候不能调用run方法,而是需要调用start()方法。

/***  本类用于演示第一种实现多线程的方式*/
class MyThread extends Thread{// 需要我们使用多进程运行的代码就写在run方法里@Overridepublic void run() {		for (int i = 1; i < 5; i++) {	System.out.println(Thread.currentThread().getName() + "线程正在运行~~~~~~" + i);}}
}
public class ThreadDemo01 extends Thread{public static void main(String[] args) {MyThread thread = new MyThread();thread.start();for (int i = 1; i < 5; i++) {	System.out.println(Thread.currentThread().getName() + "线程正在运行======" + i);}}
}

运行结果:(两个线程同时运行,争抢cpu,每次执行结果不固定)

095324984285411420146f60baf28e6b.png

12.2 实现Runnable接口

需要我们创建的线程类实现Runnable接口。实现run方法,把需要多线程调用的代码写在run方法中。由于Runnable接口中只有一个run方法,所以不能直接调用start()。这个时候需要创建一个Thread类的对象来帮助我们开启线程。创建这个Thread类对象的时候需要将我们的线程类作为参数传递给Thread对象。

/***  本类用于演示第二种实现多线程的方式*/
class MyThread2 implements Runnable{// 需要我们使用多进程运行的代码就写在run方法里@Overridepublic void run() {		for (int i = 1; i < 5; i++) {	System.out.println(Thread.currentThread().getName() + "线程正在运行~~~~~~" + i);}}
}public class ThreadDemo02 {public static void main(String[] args) {	 MyThread2 myThread2 = new MyThread2();// myThread2.run();// 由于Runable接口只有一个run方法,所以实现Runnable接口的这种方式,线程本身没有start方法。// 但是必须要调用start方法才能开启多线程,所以需要创建Thread类的对象,把我们的线程类作为参数传递给构造方法。Thread thread = new Thread(myThread2);thread.start();for (int i = 1; i < 5; i++) {	System.out.println(Thread.currentThread().getName() + "线程正在运行~~~~~~" + i);}	}
}

运行结果:(两个线程同时运行,争抢cpu,每次执行结果不固定)

de0feecec466505cd78dd1addde3f48b.png

2.3 实现Callable接口

采用实现Callable接口实现多线程启动方式以上两种的方式不太一样,下面就看一下怎样启动采用实现Callable接口的线程。

第一步:定义一个类实现Callable接口,并且指定call()返回值的类型。将业务逻辑写在call()方法中。

第二步:创建FutureTask对象,并将Callable对象传入FutureTask的构造方法中。

第三步:实例化Thread对象,并在构造方法中传入FurureTask对象。

第四步:启动线程

/***  本类用于演示第三种实现多线程的方式*/
class MyCallable implements Callable<String>{@Overridepublic String call() throws Exception {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "线程正在运行~~~~~" + i);}return "MyCallable接口执行完成!";}	}
public class ThreadDemo03 {public static void main(String[] args) throws  Exception {// 1、创建FutureTask实例,创建MyCallable实例FutureTask<String> futureTask = new FutureTask<>(new MyCallable());// 2、创建Thread实例,来执行futureTaskThread thread = new Thread(futureTask);thread.start();// 3、主线程for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "线程正在运行~~~~~" + i);}// 4、获取执行结果System.out.println(futureTask.get());}
}

运行结果:

18167ebcc76461795e4b68d46fd1b842.png

1.4 线程池

在一个应用程序中,我们需要多次使用线程,也就意味着,我们需要多次创建并销毁线程。而创建并销毁线程的过程势必会消耗内存。而在Java中,内存资源是及其宝贵的,所以,我们就提出了线程池的概念。

线程池:Java中开辟出了一种管理线程的概念,这个概念叫做线程池,从概念以及应用场景中,我们可以看出,线程池的好处,就是可以方便的管理线程,也可以减少内存的消耗。

那么,我们应该如何创建一个线程池那?Java中已经提供了创建线程池的一个类:Executor而我们创建时,一般使用它的子类:ThreadPoolExecutor。

第一步:使用Executors获取线程池对象;

第二步:通过线程池获取对象获取线程并执行Runable子类实例;

class MyThread4 implements Runnable{// 需要我们使用多进程运行的代码就写在run方法里@Overridepublic void run() {		for (int i = 1; i < 5; i++) {	System.out.println(Thread.currentThread().getName() + "线程正在运行~~~~~~" + i);}}
}
public class ThreadDemo04 {public static void main(String[] args) {	// 第一步:使用Executors获取线程池对象;ExecutorService executorService = Executors.newFixedThreadPool(10);// 第二步:通过线程池获取对象获取线程并执行Runable实例;executorService.execute(new MyThread4());		for (int i = 1; i < 5; i++) {	System.out.println(Thread.currentThread().getName() + "线程正在运行~~~~~~" + i);}		}
}

运行结果:

99d99d14bee9d16ec1a7e365a94ff7f2.png

二、总结

2.1 实现接口和继承Thread类比较

(1)接口更适合多个相同的程序代码的线程去共享同一个资源。

实现Runnable接口这种方式,可以把多线程之间相同的操作放到一个Runnable接口的run方法中实现,然后可以通过多个thread来执行同一个Runnable实例。可以达到在一个地方开发,多个地方使用,做到代码的复用。

(2)接口可以避免Java中单继承的局限性。

Java的设计是单继承的设计,如果采用继承Thread的方式实现多线程,则不能继承其他的类,就会错失继承很多父类方法。

(3)接口代码可以被多个线程共享,代码和线程独立。

(4)线程池只能放入实现Runnable或Callable接口的线程,不能直接放入继承Thread的类。

2.2 Runnable和Callable接口比较

A、相同点:

(1)两者都是接口;

(2)都可以用来编写多线程程序;

(3)两者都需要调用Thread.start()启动线程;

B、不同点:

(1)实现Callable接口的线程能返回执行结果;而实现Runnable接口的线程不能返回结果;若需要用这个线程执行任务,不需要控制则建议使用Runnable,若需要动态监控任务则建议使用Callable。

(2)Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法不允许抛异常。

(3)实现Callable接口的线程可以调用Future.cancel取消执行,而实现Runnable接口的线程不能。

注意点:Callable接口支持返回执行结果,此刻需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取“将来”结果;不调用此方法时,主线程不会阻塞。只能在不需要并发的地方调用get()方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

struts2的namespace的问题

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <inc…

JS_16闭包

闭包 什么是闭包 理解1&#xff1a;闭包是嵌套的内部函数理解2&#xff1a;闭包是包含被引用变量&#xff08;函数&#xff09;的对象 闭包产生的条件 函数嵌套子函数调用了父函数的数据父函数被调用了&#xff08;子函数不一定需要被调用&#xff0c;只需要执行函数定义即可&…

[Intel Edison开发板] 02、Edison开发板入门

一、前言 Start from the link: 开始学习的链接 上面链接是官网的教程&#xff0c;按照教程可以开发板入门&#xff1a; 其中第一步是了解开发板&#xff0c;涉及到如何组装、如何连线、一些主要的接口简单介绍等信息&#xff1b;第二步主要是介绍如何用官方提供的工具进行配置…

python apscheduler一次只有一个job_Python使用APScheduler实现定时任务过程解析

前言APScheduler是基于Quartz的一个Python定时任务框架。提供了基于日期、固定时间间隔以及crontab类型的任务&#xff0c;并且可以持久化任务。一、安装APSchedulerpip install apscheduler二、基本概念APScheduler有四大组件&#xff1a;1、触发器 triggers &#xff1a;触发…

java web service简单示例

http://www.iteye.com/topic/1135747 转载于:https://www.cnblogs.com/fycct/p/5669420.html

shell统计指定目录下所有文件类型及数量

#!/bin/bash#Synopsis:用于统计脚本当前所在目录或者用户指定目录下的所有文件类型及数量#若直接运行脚本而不接任何命令行参数,则默认会统计脚本所在目录下的文件#Date:2016/10#Author:Jian#Usage:sh fileStat.sh /path1 /path2testFile$(mktemp /tmp/testfile.XXX)#如果没有指…

python cross val score_sklearn函数:cross_val_score(交叉验证评分)

sklearn.model_selection.cross_val_score(estimator,X,yNone,*,groupsNone,scoringNone,cvNone,n_jobsNone,verbose0,fit_paramsNone,pre_dispatch2*n_jobs,error_scorenan)前面我们提到了4种分割数据集的方法&#xff0c;在分割完数据集后&#xff0c;我们训练模型&#xff0…

JS_17 ES5,ES6

ES5 严格模式 定义方法 use strict特性&#xff1a; 必须使用var定义变量存在eval作用域禁止自定义函数中的this指向window对象不能有重名属性 JSON对象 json.stringify(obj/arr):js对象转换为json对象json.parse(str):json对象转换为js对象 Object拓展 Object.create(p…

几种纯css布局的导航栏

1.垂直导航栏 页面效果 <ul class"nav"><li><a href"home.htm">Home</a></li><li><a href"about.htm">About</a></li><li><a href"services.htm">Services</a&…

python中函数的参数传递(传值还是传引用)

函数的参数传递 函数参数传递有两种方式&#xff0c;传值和传引用&#xff0c;传值只是把变量的值复制一份给了实参&#xff0c;函数内部的操作不会改变函数外部变量的值&#xff0c;而传引用传递的是外部变量的地址&#xff0c;函数内部直接操作函数外部变量的储存空间&#…

poi获取有效单元格个数_EXCEL利用SUM函数和FREQUENCY函数数组公式统计不同区间数据个数...

EXCEL函数公式大全之利用FREQUENCY函数数组公式统计不同区间数据个数。EXCEL函数与公式在工作中使用非常的频繁&#xff0c;会不会使用公式直接决定了我们的工作效率&#xff0c;今天我们来学习一下提高我们工作效率的函数FREQUENCY函数和数组公式。今天我们的例子是统计学生在…

windows安装rsync

客户端&#xff1a;cwRsync 4.0.5 Installer服务端&#xff1a;cwRsyncServer 4.0.5 Installer 安装配置Rsync服务端 1.直接双击安装包安装即可&#xff0c;在安装过程中会有要求用户输入账户密码或者使用默认。此账户是rsync服务运行的用户。 2.安装完成之后&#xff0c;进入程…

洛谷 P2735 电网 Electric Fences Label:计算几何--皮克定理

题目描述 在本题中&#xff0c;格点是指横纵坐标皆为整数的点。 为了圈养他的牛&#xff0c;农夫约翰&#xff08;Farmer John)建造了一个三角形的电网。他从原点&#xff08;0,0&#xff09;牵出一根通电的电线&#xff0c;连接格点(n,m)&#xff08;0<n<32000,0<m&l…

Python元类(type()和metaclass)

1. 元类是什么 众所周知&#xff0c;对象由类实例化而来&#xff0c;类是对象的模板&#xff0c;而python一切皆对象&#xff0c;类也是对象&#xff0c;它由元类&#xff08;type&#xff09;创建&#xff0c;所以元类是类的类&#xff0c;是类的模板 2. 创建类的另一种方法…

word文档打印 自动编码_办公室文件打印有哪些技巧 办公室文件打印技巧介绍【图文】...

办公室文件打印实用技巧三则一. 打印文件直接装订——逆序打印相信使用Word打印过长篇文档的朋友一定都清楚&#xff0c;打印完成后的装订一直是个麻烦事儿&#xff0c;因为文件由打印机打出时&#xff0c;第一页肯定会在最下面&#xff0c;装订之前总要费时费力的把纸张按顺序…

Strategy 策略模式

意图 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。 动机 策略模式为了适应不同的需求&#xff0c;只把变化点封装了&#xff0c;这个变化点就是实现不同需求的算法&#xff0c;但是&#xff0c;用户需要知道各种…

python 消息中间件_消息队列中间件 RabbitMQ 详细介绍——安装与基本应用(Python)...

RabbitMQ 是当前最流行的消息中间件(Message Broker)之一&#xff0c;支持多种消息协议(如 AMQP、MQTT)。同时它也是一个轻量级的非常易于部署的开源软件&#xff0c;可以运行在当前大多数操作系统及云端环境中&#xff0c;也能够部署在分布式的集群环境里以达到高可用、可伸缩…

用 Flask 来写个轻博客 (1) — 创建项目

目录 目录前言扩展阅读部署开发环境创建 Github 项目前言 一步一步的实现一个 Flask 轻博客项目启动&#xff0c;最新的代码会上传到 Github。 扩展阅读 欢迎使用 Flask — virtualenv 部署开发环境 连接 GitHubhostnamectl set-hostname flask-dev # 设置 hostname ssh-keyg…

python静态方法,类方法,属性方法,实例方法

DAY 3. 静态方法&#xff0c;类方法&#xff0c;属性方法&#xff0c;实例方法 有四种方法&#xff0c;实例方法&#xff0c;类方法&#xff0c;静态方法&#xff0c;属性方法 实例方法 实例方法的第一个参数是self&#xff0c;他会指向类的实例化对象&#xff0c;只能被对象…

ubuntu 软件包降级

ubuntu 软件包降级 sudo aptitude install libssl-dev 1. 是否接受该解决方案&#xff1f; [Y/n/?] n 2. 是否接受该解决方案&#xff1f; [Y/n/?] y 3. 您要继续吗&#xff1f; [Y/n/?] ysudo aptitude install libcairo21.4.10-1ubuntu4 # 强制降级 sudo aptitude forbid…