并发(Concurrent):在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。
同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。
并行(Parallel):当系统有一个以上CPU时,当一个CPU执行一个进程时,另一个CPU可以执行另一个进程,两个进程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。其实决定并行的因素不是CPU的数量,而是CPU的核心数量,比如一个CPU多个核也可以并行。
进程(Process):是正在运行的程序实体,并且包括这个运行的程序中占据的所有系统资源,比如说CPU(寄存器),IO,内存,网络资源等。同样一个程序,同一时刻被两次运行了,那么他们就是两个独立的进程。
线程(Thread):是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
进程与线程的区别:
多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理或同时多线程处理器。在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理“。
优点:
(1) 用户界面可以在进行其它工作的同时CPU一直处于活动状态,可以让程序运行速度更快。
(2)占用大量处理时间的任务可以定期将处理器时间让给其它任务,可以提高CPU利用率。
使用实例演示多线程好处(在了解了多线程实现方式之后进行编写)
package com.aaa.mt.demo3;
import java.io.*;
/**
* @ fileName:PingIP
* @ description:
* @ author:zhz
* @ createTime:2021/11/30 10:58
* @ version:1.0.0
*/
public class PingIP {
/**
* 封装pingIP方法
* @param ip
*/
public static void pingIP(String ip){
InputStream inputStream = null;
BufferedReader bufferedReader = null;
try {
//Runtime每个Java应用程序都有一个Runtime类的Runtime ,允许应用程序与运行应用程序的环境进行接口。
Runtime runtime = Runtime.getRuntime();
//使用与环境接口的类的exec 可以得到当前运行进程类
Process process = runtime.exec("ping "+ip);
//获取到执行结果流
inputStream = process.getInputStream();
//BufferedReader使用按行读取的字符流并提高效率
//InputStreamReader 把字节流转字符流的类
bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"GBK"));
//定义变量接受读的字符串
String charLine = null;
//定义是否ping得通得标识符
boolean isSuc =false;
//按行读取
while((charLine=bufferedReader.readLine())!=null){
if(charLine.indexOf("TTL")!=-1){
isSuc=true;
break;
}
}
if(isSuc){
System.out.println(ip+"通");
}else{
System.out.println(ip+"不通");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(inputStream!=null){
inputStream.close();
}
if(bufferedReader!=null){
bufferedReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
//返回1970-1-1午夜到现在的毫秒数
long startTime = System.currentTimeMillis();
for (int i = 1; i <= 20; i++) {
pingIP("192.168.41."+i);
}
long endTime = System.currentTimeMillis();
System.out.println("用时:"+(endTime-startTime)/1000);
}
}
package com.aaa.mt.demo3;
/**
* @ fileName:MTPingIP
* @ description:
* @ author:zhz
* @ createTime:2021/11/30 11:24
* @ version:1.0.0
*/
public class MTPingIP extends Thread {
private String ip;
public MTPingIP(String ip) {
this.ip = ip;
}
@Override
public void run() {
//执行业务代码
PingIP.pingIP(ip);
}
}
package com.aaa.mt.demo3;
/**
* @ fileName:Test
* @ description:
* @ author:zhz
* @ createTime:2021/11/30 11:27
* @ version:1.0.0
*/
public class Test {
public static void main(String[] args) {
//返回1970-1-1午夜到现在的毫秒数
long startTime = System.currentTimeMillis();
// main线程 它和启动20个线程是并行运行
System.out.println("当前线程名称"+Thread.currentThread().getName());
for (int i = 1; i <= 20; i++) {
//循环启动20线程 20个线程一起ping
new MTPingIP("192.168.41."+i).start();
}
long endTime = System.currentTimeMillis();
System.out.println("用时:"+(endTime-startTime)/1000);
}
}
缺点:
(1)等候使用共享资源时造成程序的运行速度变慢。这些共享资源主要是独占性的资源 ,如打印机等。
(2)对线程进行管理要求额外的 CPU开销,线程的使用会给系统带来上下文切换的额外负担。
(3)线程的死锁。即对共享资源加锁实现同步的过程中可能会死锁。(后面有实例)
1,继承thread
package com.aaa.mt.demo1;
/**
* @ fileName:MTExtendsThread
* @ description:继承Thread完成多线程
* @ author:zhz
* @ createTime:2021/11/30 9:22
* @ version:1.0.0
*/
public class MTExtendsThread extends Thread{
@Override
public void run() {
//执行线程业务的方法
for (int i = 0; i < 10; i++) {
//返回正在执行的线程实例
Thread thread = Thread.currentThread();
//getName()获取当前线程实例的名称
System.out.println(thread.getName()+"执行打印"+i);
}
}
}
2 , 实现Runnable
package com.aaa.mt.demo1;
/**
* @ fileName:MTImplementsRunnable
* @ description:
* @ author:zhz
* @ createTime:2021/11/30 9:36
* @ version:1.0.0
*/
public class MTImplementsRunnable implements Runnable{
@Override
public void run() {
//执行线程业务的方法
for (int i = 0; i < 10; i++) {
//返回正在执行的线程实例
Thread thread = Thread.currentThread();
//getName()获取当前线程实例的名称
System.out.println(thread.getName()+"执行打印"+i);
}
}
}
3,实现Callable
package com.aaa.mt.demo1;
import java.util.UUID;
import java.util.concurrent.Callable;
/**
public class MTImplementsCallable implements Callable {
@Override
public Object call() throws Exception {
//执行线程业务的方法
for (int i = 0; i < 10; i++) {
//返回正在执行的线程实例
Thread thread = Thread.currentThread();
//getName()获取当前线程实例的名称
System.out.println(thread.getName()+"执行打印"+i);
}
//获取随机数
UUID uuid = UUID.randomUUID();
System.out.println("随机数字符串为:"+uuid);
System.out.println(1/0);
return uuid;
}
}
4,使用线程池
package com.aaa.mt.demo1;
/**
* @ fileName:MTPool
* @ description:
* @ author:zhz
* @ createTime:2021/11/30 10:30
* @ version:1.0.0
*/
public class MTPool implements Runnable {
@Override
public void run() {
//执行线程业务的方法
for (int i = 0; i < 10; i++) {
//返回正在执行的线程实例
Thread thread = Thread.currentThread();
//getName()获取当前线程实例的名称
System.out.println(thread.getName()+"执行打印"+i);
}
}
}
//实例化线程类
MTPool mtPool =new MTPool();
//使用Executors创建固定长度为4的线程池
ExecutorService executorService = Executors.newFixedThreadPool(4);
//调用execute启动线程
executorService.execute(mtPool);
1,都是执行多线程,但是方法名称不同 run() 和call()
2, 实现Runnable方法是没有返回值,无法获取线程业务方法执行结果 而Callable相反
3, 实现Runnable方法没有抛出异常 而Callable有异常处理,并且获取异常
一个类只能继承一个父类,存在局限;一个类可以实现多个接口。在实现Runnable接口的时候调用Thread的Thread(Runnable run)或者Thread(Runnable run,String name)构造方法创建进程时,使用同一个Runnable实例,建立的多线程的实例变量也是共享的;但是通过继承Thread类是不能用一个实例建立多个线程,故而实现Runnable接口适合于资源共享;当然,继承Thread类也能够共享变量,能共享Thread类的static变量;
使用卖票实例演示上面表述:
package com.aaa.mt.demo2;
/**
* @ fileName:SellTicketExtendsThread
* @ description: 使用多线程卖票,继承Thread来实现业务
* @ author:zhz
* @ createTime:2021/11/30 10:40
* @ version:1.0.0
*/
public class SellTicketExtendsThread extends Thread {
//定义总票数
private int ticketNum = 20;
//卖票人姓名
private String name;
/**
* 构造方法
* @param name
*/
public SellTicketExtendsThread(String name) {
this.name = name;
}
@Override
public void run() {
while(ticketNum>0){
System.out.println(name+"正在卖票,剩余"+(--ticketNum)+"张");
}
}
}
package com.aaa.mt.demo2;
/**
* @ fileName:SellTicketImplementsRunnable
* @ description:
* @ author:zhz
* @ createTime:2021/11/30 10:49
* @ version:1.0.0
*/
public class SellTicketImplementsRunnable implements Runnable{
//定义总票数
private int ticketNum = 20;
@Override
public void run() {
while(ticketNum>0){
System.out.println(Thread.currentThread().getName()+"正在卖票,剩余"+(--ticketNum)+"张");
}
}
}
package com.aaa.mt.demo2;
/**
* @ fileName:Test
* @ description:
* @ author:zhz
* @ createTime:2021/11/30 10:45
* @ version:1.0.0
*/
public class Test {
public static void main(String[] args) {
/* SellTicketExtendsThread sellTicketExtendsThread =new SellTicketExtendsThread("马云");
sellTicketExtendsThread.start();
*//* sellTicketExtendsThread.start();
sellTicketExtendsThread.start();*//*
SellTicketExtendsThread sellTicketExtendsThread1 =new SellTicketExtendsThread("马化腾");
sellTicketExtendsThread1.start();
SellTicketExtendsThread sellTicketExtendsThread2 =new SellTicketExtendsThread("刘强东");
sellTicketExtendsThread2.start();*/
SellTicketImplementsRunnable sellTicketImplementsRunnable =new SellTicketImplementsRunnable();
new Thread(sellTicketImplementsRunnable,"马云").start();
new Thread(sellTicketImplementsRunnable,"马化腾").start();
new Thread(sellTicketImplementsRunnable,"刘强东").start();
}
}
package com.aaa.mt.demo4;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* @ fileName:AnonymousInternalClass
* @ description:
* @ author:zhz
* @ createTime:2021/11/30 11:35
* @ version:1.0.0
*/
public class AnonymousInternalClass {
public static void main(String[] args) {
//继承Thread启动线程
new Thread(){
@Override
public void run() {
for (int i = 0; i < 10; i++) {
//返回正在执行的线程实例
Thread thread = Thread.currentThread();
//getName()获取当前线程实例的名称
System.out.println(thread.getName()+"执行打印"+i);
}
}
}.start();
System.out.println("-------------------------------------");
//实现Runnable
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
//返回正在执行的线程实例
Thread thread = Thread.currentThread();
//getName()获取当前线程实例的名称
System.out.println(thread.getName()+"执行打印"+i);
}
}
}).start();
System.out.println("-------------------------------------");
//实现Callable
new Thread(new FutureTask<String>(
new Callable<String>() {
@Override
public String call() throws Exception {
for (int i = 0; i < 10; i++) {
//返回正在执行的线程实例
Thread thread = Thread.currentThread();
//getName()获取当前线程实例的名称
System.out.println(thread.getName()+"执行打印"+i);
}
return null;
}
})).start();
}
}
currentThread() 返回对当前正在执行的线程对象的引用。
setName(String name) 将此线程的名称更改为等于参数 name 。(具体用法参考项目demo4包)
getName() 返回此线程的名称。
start() 导致此线程开始执行; Java虚拟机调用此线程的run方法。
run() 如果这个线程使用单独的Runnable运行对象构造,则调用该Runnable对象的run方法; 否则,此方法不执行任何操作并返回。 线程执行业务的方法。
setPriority(int newPriority) 更改此线程的优先级。
getPriority() 返回此线程的优先级。
sleep(long millis) 使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。
stop() 强制结束当前线程。Deprecated
join() 等待这个线程死亡。一旦调用一个线程的join方法后,当前线程产生阻塞,直到在调用 join方法的线程执行完毕后,再去执行。
yield() 对调度程序的一个暗示,即当前线程愿意暂时让出当前使用的处理器。当前让出执行权。
五种状态:
文章浏览阅读536次。这个布局不要写错了。这个是fragment.xml。
文章浏览阅读5.4k次,点赞3次,收藏42次。源自:计算机集成制造系统作者:陶飞 张贺 戚庆林 徐 俊 孙铮 胡天亮 刘晓军 刘庭煜 关俊涛 陈畅宇 孟凡伟 张辰源 李志远 魏永利 朱铭浩 肖斌数字孪生作为实现数字化转型和促进智能化升级的重要使能途径,一直备受各行各业关注,已从理论研究走向了实际应用阶段。数字孪生是以多维虚拟模型和融合数据双驱动,通过虚实闭环交互,来实现监控、仿真、预测、优化等实际功能服务和应用需求,其中数字孪生模型构建是实现数字孪生落地应用的前提。_数字孪生模型
文章浏览阅读1.3k次。spring揭秘这本权威书籍阅读后的总结分享,希望能帮助到你_spring ioc容器
文章浏览阅读6.4k次,点赞2次,收藏12次。实例1.select top 10 * from 成绩信息 作用:查询前十行数据2.select top 10 percent * from 成绩信息 作用:查询前10%行的数据3.declare @i int set @i=20 select top (@i) percent * from 成绩信息声明了一个变量i为整型,然后对变量i复制为20,然后就可以限制20%行数的数据了。4.declare @i int set @i=20 ..._sql server top
文章浏览阅读2.9k次。2020牛客国庆集训派对day5 B.Hyperdrome题目链接题目描述Hypergnome planet is famous for its Great Universal Games between gnomes — the Games between gnomes from each part of the galaxy in various disciplines.The most popular discipline in the Games is the Hyperdrome disc_b\hyperdrome
文章浏览阅读7.5k次,点赞15次,收藏71次。前言 以前制作一个Python窗体界面,我都是用GUI窗口视窗设计的模块Tkinter一点一点敲出来的,今天朋友问我有没有Python窗体的设计工具,“用鼠标拖拖”就能完成窗体设计,我查了查相关资料,果然有一款好用的工具——Qt Designer。1.安装Qt Designer 这里需要安装两个东西:PyQt5和PyQt5-tools:安装PyQt5:打开CMD或者PowerShell,在命令窗中输入 pip install PyQt5 执行结果如下:..._pyqt可视化
文章浏览阅读2.9k次。或者单击FI 图标。在绘制文字命令下,按下鼠标左键即可创建文字对象。4.7.2 激光打标机软件EzCad2 支持曲线排文字,如果您单击的位置足够接近于一条曲线图形,那么您输入的文字将会随着该曲线的轨迹排列。当前文字是曲线排文字时,点击 后系统弹出如图 4-12 所示对话框 。图 4-12 曲线文字表示文字总是平行于曲 线的切线放置,如图 4-13 所示。图 4-13 正常放置表示文字总是垂直放置,..._ezcad激光打标详细教程
文章浏览阅读1.2k次。视频解析服务器异常 内容精选换一换修改DNS服务器可以很快同步到顶级域服务器并在网络中生效。但是,域名服务商处NS记录的TTL值通常设置为48小时,这样假如某些地区Local DNS缓存了域名的NS记录,则最长需要48小时才能刷新成新的NS记录,变更为修改后的DNS服务器。因此,修改域名DNS服务器的生效时间请以域名服务商处的说明为准。在等待修改生效期间,请勿删除域名在原反向解析主要应用于自建邮箱..._云聚鹰视频解析错误
文章浏览阅读1.5w次,点赞11次,收藏52次。写这篇文章的缘由是因为早上的机器学习讨论班大家对于一句话:用于向量化的k均值是高斯混合模型的一个硬版本(出处:机器学习导论,隐马尔科夫模型,p247,(15-36))产生了深刻的思考然后不理解,在结合老师的讲解以及搜索资料后,决定记录下来。这一部分属于无监督学习的内容,无监督学习内容主要包括:Kmeans聚类算法、高斯混合模型GMM及EM算法等。Kmeans聚类其实聚类算法除了Kmeans,还有其..._高斯混合模型和kmeans之间有什么区别
文章浏览阅读2.4k次。RISC是精简指令集CPU,指令位数较短,内部还有快速处理指令的电路,使得指令的译码与数据的处理较快,所以执行效率比CISC高,不过,必须经过编译程序的处理,才能发挥它的效率,我所知道的IBM的 Power PC为RISC CPU的结构,CISCO 的CPU也是RISC的结构。复杂指令集CPU内部为将较复杂的指令译码,也就是指令较长,分成几个微指令去执行,正是如此开发程序比较容易(指令多的缘故),但是由于指令复杂,执行工作效率较差,处理数据速度较慢,PC 中 Pentium的结构都为CISC CPU。_精简指令集和复杂指令集
文章浏览阅读1.3k次。每次启动linux版WPS就会弹出“系统缺失字体……”提醒对话框,对于系统缺失字体有以下几种:wingdings、wingdings 2、wingdings 3、Webdings、MT Extra,下面就来讲解如何让系统不缺失这些字体呢?从网上找到wingdings、wingdings 2、wingdings 3、Webdings、MT Extra这些字体进入主文件夹,按Ctrl+h键(显示隐藏文..._wps提示方正黑体_gbk对系统无效
文章浏览阅读1.6w次,点赞18次,收藏178次。**利用MATLAB对一张图片中相同得物体进行计数。**MATLAB中已有函数可对二值化中的白色区域进行计数。[labeled,numObjects]=bwlabel(‘图像名’,8);运行后numObjects(即物体个数)的值会显示在右侧的工作区中。因此我们需要做的是对图像进行处理,包括二值化,除噪等。若直接将图像转化为二值图像进行计数,则无法得到正确数据。如clc;clo..._matlab特殊形状计数