当前位置: 首页 > 编程日记 > 正文

Java高级特性增强-多线程

请戳GitHub原文: https://github.com/wangzhiwub...

大数据成神之路系列:

请戳GitHub原文: https://github.com/wangzhiwub...

Java高级特性增强-集合

Java高级特性增强-多线程

Java高级特性增强-Synchronized

Java高级特性增强-volatile

Java高级特性增强-并发集合框架

Java高级特性增强-分布式

Java高级特性增强-Zookeeper

Java高级特性增强-JVM

Java高级特性增强-NIO

Java高级特性增强-多线程

本部分网络上有大量的资源可以参考,在这里做了部分整理,感谢前辈的付出,每节文章末尾有引用列表,源码推荐看JDK1.8以后的版本,注意甄别~

多线程

集合框架

NIO

Java并发容器

公众号

  • 全网唯一一个从0开始帮助Java开发者转做大数据领域的公众号~
  • 公众号大数据技术与架构或者搜索import_bigdata关注,大数据学习路线最新更新,已经有很多小伙伴加入了~

    • *

Java高级特性增强-多线程

本部分网络上有大量的资源可以参考,在这里做了部分整理,感谢前辈的付出,每节文章末尾有引用列表,源码推荐看JDK1.8以后的版本,注意甄别~

多线程

集合框架

NIO

Java并发容器

    • *

多线程

进程和多线程简介

进程和线程

进程和线程的对比这一知识点由于过于基础,所以在面试中很少碰到,但是极有可能会在笔试题中碰到。常见的提问形式是这样的:“什么是线程和进程?,请简要描述线程与进程的关系、区别及优缺点? ”。

何为进程?

进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。
或者我们可以这样说:
进程,是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。

何为线程?

线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。

何为多线程

多线程就是多个线程同时运行或交替运行。单核CPU的话是顺序执行,也就是交替运行。多核CPU的话,因为每个CPU有自己的运算器,所以在多个CPU中可以同时运行。

为什么多线程是必要的

个人觉得可以用一句话概括:开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。

为什么提倡多线程而不是多进程

线程就是轻量级进程,是程序执行的最小单位。使用多线程而不是用多进程去进行并发程序的设计,是因为线程间的切换和调度的成本远远小于进程。

线程有什么优缺点

1)好处
使用多线程可以把程序中占据时间长的任务放到后台去处理,如图片、视屏的下载。
发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好。
2)坏处
大量的线程降低代码的可读性。
更多的线程需要更多的内存空间。
当多个线程对同一个资源出现争夺时候要注意线程安全的问题。

多线程中重要的概念

同步和异步
同步和异步通常用来形容一次方法调用。同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者可以继续后续的操作。

关于异步目前比较经典以及常用的实现方式就是消息队列:在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即 返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。

并发(Concurrency)和并行(Parallelism)
并发和并行是两个非常容易被混淆的概念。它们都可以表示两个或者多个任务一起执行,但是偏重点有些不同。并发偏重于多个任务交替执行,而多个任务之间有可能还是串行的。而并行是真正意义上的“同时执行”。

多线程在单核CPU的话是顺序执行,也就是交替运行(并发)。多核CPU的话,因为每个CPU有自己的运算器,所以在多个CPU中可以同时运行(并行)。

高并发
高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。

高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等。

临界区
临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用。但是每一次,只能有一个线程使用它,一旦临界区资源被占用,其他线程要想使用这个资源,就必须等待。在并行程序中,临界区资源是保护的对象。

阻塞和非阻塞
非阻塞指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回,而阻塞与之相反。

多线程的创建方式

继承Thread类

public class MyThread extends Thread {@Overridepublic void run() {super.run();System.out.println("MyThread");}
}

实现Runnable接口

public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("MyRunnable");}
}

线程池

《阿里巴巴Java开发手册》在第一章第六节并发处理这一部分也强调到“线程资源必须通过线程池提供,不允许在应用中自行显示创建线程”。
我们在实际开发环境中,建议使用线程池的方式创建线程。
public class ThreadPool
{private static int POOL_NUM = 10;public static void main(String[] args){
ExecutorService executorService =               Executors.newFixedThreadPool(5);for(int i = 0; i<POOL_NUM; i++){RunnableThread thread = new RunnableThread();executorService.execute(thread);}}
}class RunnableThread implements Runnable
{private int THREAD_NUM = 10;public void run(){for(int i = 0; i<THREAD_NUM; i++){System.out.println("线程" + Thread.currentThread() + " " + i);} }
}
线程的生命周期

线程一共有五个状态,分别如下:
新建(new):
当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。例如:Thread t1 = new Thread() 。

可运行(runnable):
线程对象创建后,其他线程(比如 main 线程)调用了该对象的 start 方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取 cpu 的使用权。例如:t1.start() 。

运行(running):
线程获得 CPU 资源正在执行任务(#run() 方法),此时除非此线程自动放弃 CPU 资源或者有优先级更高的线程进入,线程将一直运行到结束。
死亡(dead):当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
自然终止:
正常运行完 #run()方法,终止。
异常终止:
调用 #stop() 方法,让一个线程终止运行。
堵塞(blocked):
由于某种原因导致正在运行的线程让出 CPU 并暂停自己的执行,即进入堵塞状态。直到线程进入可运行(runnable)状态,才有机会再次获得 CPU 资源,转到运行(running)状态。阻塞的情况有三种:
正在睡眠:
调用 #sleep(long t) 方法,可使线程进入睡眠方式。
一个睡眠着的线程在指定的时间过去可进入可运行(runnable)状态。
正在等待:
调用 #wait() 方法。
调用 notify() 方法,回到就绪状态。
被另一个线程所阻塞:
调用 #suspend() 方法。
调用 #resume() 方法,就可以恢复。

线程的优先级

每个线程都具有各自的优先级,线程的优先级可以在程序中表明该线程的重要性,如果有很多线程处于就绪状态,系统会根据优先级来决定首先使哪个线程进入运行状态。但这个并不意味着低。
优先级的线程得不到运行,而只是它运行的几率比较小,如垃圾回收机制线程的优先级就比较低。所以很多垃圾得不到及时的回收处理。

线程优先级具有继承特性比如A线程启动B线程,则B线程的优先级和A是一样的。

线程优先级具有随机性也就是说线程优先级高的不一定每一次都先执行完。

Thread类中包含的成员变量代表了线程的某些优先级。如Thread.MIN_PRIORITY(常数1),Thread.NORM_PRIORITY(常数5),
Thread.MAX_PRIORITY(常数10)。其中每个线程的优先级都在Thread.MIN_PRIORITY(常数1) 到Thread.MAX_PRIORITY(常数10) 之间,在默认情况下优先级都是Thread.NORM_PRIORITY(常数5)。

学过操作系统这门课程的话,我们可以发现多线程优先级或多或少借鉴了操作系统对进程的管理

线程的终止

interrupt()方法
注意:interrupt()方法的使用效果并不像for+break语句那样,马上就停止循环。调用interrupt方法是在当前线程中打了一个停止标志,并不是真的停止线程。

public class MyThread extends Thread {public void run(){super.run();for(int i=0; i<500000; i++){System.out.println("i="+(i+1));}}
}public class Run {public static void main(String args[]){Thread thread = new MyThread();thread.start();try {Thread.sleep(2000);thread.interrupt();} catch (InterruptedException e) {e.printStackTrace();}}
}

输出结果:

...
i=499994
i=499995
i=499996
i=499997
i=499998
i=499999
i=500000

判断线程是否停止状态
Thread.java类中提供了两种方法:

this.interrupted(): 测试当前线程是否已经中断;
this.isInterrupted(): 测试线程是否已经中断;
那么这两个方法有什么图区别呢?
我们先来看看this.interrupted()方法的解释:测试当前线程是否已经中断,当前线程是指运行this.interrupted()方法的线程。

public class MyThread extends Thread {public void run(){super.run();for(int i=0; i<500000; i++){i++;}}
}public class Run {public static void main(String args[]){Thread thread = new MyThread();thread.start();try {Thread.sleep(2000);thread.interrupt();System.out.println("stop 1->" + thread.interrupted());System.out.println("stop 2->" + thread.interrupted());} catch (InterruptedException e) {e.printStackTrace();}}
}

运行结果:

stop 1->false
stop 2->false

类Run.java中虽然是在thread对象上调用以下代码:thread.interrupt(), 后面又使用

System.out.println("stop 1->" + thread.interrupted());
System.out.println("stop 2->" + thread.interrupted());  

来判断thread对象所代表的线程是否停止,但从控制台打印的结果来看,线程并未停止,这也证明了interrupted()方法的解释,测试当前线程是否已经中断。这个当前线程是main,它从未中断过,所以打印的结果是两个false.

如何使main线程产生中断效果呢?

public class Run2 {public static void main(String args[]){Thread.currentThread().interrupt();System.out.println("stop 1->" + Thread.interrupted());System.out.println("stop 2->" + Thread.interrupted());System.out.println("End");}
}    

运行结果为:

stop 1->true
stop 2->false
End

方法interrupted()的确判断出当前线程是否是停止状态。但为什么第2个布尔值是false呢? 官方帮助文档中对interrupted方法的解释:
测试当前线程是否已经中断。线程的中断状态由该方法清除。 换句话说,如果连续两次调用该方法,则第二次调用返回false。

下面来看一下inInterrupted()方法。

public class Run3 {public static void main(String args[]){Thread thread = new MyThread();thread.start();thread.interrupt();System.out.println("stop 1->" + thread.isInterrupted());System.out.println("stop 2->" + thread.isInterrupted());}
}

运行结果:

stop 1->true
stop 2->true

isInterrupted()并为清除状态,所以打印了两个true。

能停止的线程--异常法
有了前面学习过的知识点,就可以在线程中用for语句来判断一下线程是否是停止状态,如果是停止状态,则后面的代码不再运行即可:

public class MyThread extends Thread {public void run(){super.run();for(int i=0; i<500000; i++){if(this.interrupted()) {System.out.println("线程已经终止, for循环不再执行");break;}System.out.println("i="+(i+1));}}
}public class Run {public static void main(String args[]){Thread thread = new MyThread();thread.start();try {Thread.sleep(2000);thread.interrupt();} catch (InterruptedException e) {e.printStackTrace();}}
}

运行结果:

...
i=202053
i=202054
i=202055
i=202056
线程已经终止, for循环不再执行

上面的示例虽然停止了线程,但如果for语句下面还有语句,还是会继续运行的。看下面的例子:

public class MyThread extends Thread {public void run(){super.run();for(int i=0; i<500000; i++){if(this.interrupted()) {System.out.println("线程已经终止, for循环不再执行");break;}System.out.println("i="+(i+1));}System.out.println("这是for循环外面的语句,也会被执行");}
}

使用Run.java执行的结果是:

...
i=180136
i=180137
i=180138
i=180139
线程已经终止, for循环不再执行
这是for循环外面的语句,也会被执行

如何解决语句继续运行的问题呢? 看一下更新后的代码:

public class MyThread extends Thread {public void run(){super.run();try {for(int i=0; i<500000; i++){if(this.interrupted()) {System.out.println("线程已经终止, for循环不再执行");throw new InterruptedException();}System.out.println("i="+(i+1));}System.out.println("这是for循环外面的语句,也会被执行");} catch (InterruptedException e) {System.out.println("进入MyThread.java类中的catch了。。。");e.printStackTrace();}}
}

使用Run.java运行的结果如下:

...
i=203798
i=203799
i=203800
线程已经终止, for循环不再执行
进入MyThread.java类中的catch了。。。
java.lang.InterruptedExceptionat thread.MyThread.run(MyThread.java:13)

在沉睡中停止
如果线程在sleep()状态下停止线程,会是什么效果呢?

public class MyThread extends Thread {public void run(){super.run();try {System.out.println("线程开始。。。");Thread.sleep(200000);System.out.println("线程结束。");} catch (InterruptedException e) {System.out.println("在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:" + this.isInterrupted());e.printStackTrace();}}
}

使用Run.java运行的结果是:

线程开始。。。
在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:false
java.lang.InterruptedException: sleep interruptedat java.lang.Thread.sleep(Native Method)at thread.MyThread.run(MyThread.java:12)

从打印的结果来看, 如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变为false。

前一个实验是先sleep然后再用interrupt()停止,与之相反的操作在学习过程中也要注意:

public class MyThread extends Thread {public void run(){super.run();try {System.out.println("线程开始。。。");for(int i=0; i<10000; i++){System.out.println("i=" + i);}Thread.sleep(200000);System.out.println("线程结束。");} catch (InterruptedException e) {System.out.println("先停止,再遇到sleep,进入catch异常");e.printStackTrace();}}
}public class Run {public static void main(String args[]){Thread thread = new MyThread();thread.start();thread.interrupt();}
}

运行结果:

i=9998
i=9999
先停止,再遇到sleep,进入catch异常
java.lang.InterruptedException: sleep interruptedat java.lang.Thread.sleep(Native Method)at thread.MyThread.run(MyThread.java:15)

能停止的线程---暴力停止
使用stop()方法停止线程则是非常暴力的。

public class MyThread extends Thread {private int i = 0;public void run(){super.run();try {while (true){System.out.println("i=" + i);i++;Thread.sleep(200);}} catch (InterruptedException e) {e.printStackTrace();}}
}public class Run {public static void main(String args[]) throws InterruptedException {Thread thread = new MyThread();thread.start();Thread.sleep(2000);thread.stop();}
}

运行结果:

i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9Process finished with exit code 0

方法stop()与java.lang.ThreadDeath异常

调用stop()方法时会抛出java.lang.ThreadDeath异常,但是通常情况下,此异常不需要显示地捕捉。

public class MyThread extends Thread {private int i = 0;public void run(){super.run();try {this.stop();} catch (ThreadDeath e) {System.out.println("进入异常catch");e.printStackTrace();}}
}public class Run {public static void main(String args[]) throws InterruptedException {Thread thread = new MyThread();thread.start();}
}

stop()方法以及作废,因为如果强制让线程停止有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据得不到同步的处理,出现数据不一致的问题。

释放锁的不良后果

使用stop()释放锁将会给数据造成不一致性的结果。如果出现这样的情况,程序处理的数据就有可能遭到破坏,最终导致程序执行的流程错误,一定要特别注意:

public class SynchronizedObject {private String name = "a";private String password = "aa";public synchronized void printString(String name, String password){try {this.name = name;Thread.sleep(100000);this.password = password;} catch (InterruptedException e) {e.printStackTrace();}}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}public class MyThread extends Thread {private SynchronizedObject synchronizedObject;public MyThread(SynchronizedObject synchronizedObject){this.synchronizedObject = synchronizedObject;}public void run(){synchronizedObject.printString("b", "bb");}
}public class Run {public static void main(String args[]) throws InterruptedException {SynchronizedObject synchronizedObject = new SynchronizedObject();Thread thread = new MyThread(synchronizedObject);thread.start();Thread.sleep(500);thread.stop();System.out.println(synchronizedObject.getName() + "  " + synchronizedObject.getPassword());}
}

输出结果:

b  aa

由于stop()方法以及在JDK中被标明为“过期/作废”的方法,显然它在功能上具有缺陷,所以不建议在程序张使用stop()方法。

使用return停止线程
将方法interrupt()与return结合使用也能实现停止线程的效果:

 public class MyThread extends Thread {public void run(){while (true){if(this.isInterrupted()){System.out.println("线程被停止了!");return;}System.out.println("Time: " + System.currentTimeMillis());}}
}public class Run {public static void main(String args[]) throws InterruptedException {Thread thread = new MyThread();thread.start();Thread.sleep(2000);thread.interrupt();}
}

输出结果:

...
Time: 1467072288503
Time: 1467072288503
Time: 1467072288503
线程被停止了!

笔者花了巨大篇幅介绍线程的终止,因为这是在实际开发中最容易犯的错误,千万注意哦~
参考资料列表:

java并发编程指南
https://blog.csdn.net/qq_3433...

死磕系列:
http://cmsblogs.com/?p=2611

面试题系列:
https://blog.csdn.net/linzhiq...

简书:
https://www.jianshu.com/nb/48...

以上几个博客足够了,着重推荐一下死磕系列和简书的文章,比较深入

公众号

  • 全网唯一一个从0开始帮助Java开发者转做大数据领域的公众号~
  • 公众号大数据技术与架构或者搜索import_bigdata关注,大数据学习路线最新更新~

已经有很多小伙伴加入啦~

相关文章:

微软企业库4.1学习笔记(八)创建对象 续集2

3.3通过配置指定和Unity的整合 另外一种方法是在配置源中指定配置的需要&#xff0c;你可以指定下面的一条或者多条&#xff1a; 你可以在Unity配置中指定想要的BlockExtensions  你可以在Unity配置中的type配置节指定如何创建企业库对象&#xff0c;指定类型映射的关系&…

Kali Linux python 安装pip

安装pip&#xff1a;apt-get install python-setuptoolseasy_install pippip install xxxx转载于:https://www.cnblogs.com/arhatlohan/p/4737828.html

3dmax图像采样器抗锯齿_内幕揭秘!同样的场景同一张图,用3DMAX网渲平台进行二次渲染时间竟然相差3个小时之多!...

一个分辨率:4000*2000的室内客餐厅&#xff0c;3dmax版本是2014版本&#xff0c;渲染器版本为vray3.63&#xff0c;机器&#xff1a;阿里云1台服务器&#xff0c;这个同样的场景同样的参数同一张图&#xff0c;用3dmax网渲平台进行二次渲染发现时间相差了将近3个小时之多&#…

2015/8/18

一、git, switch to找不到师傅新创的branch 解决方法&#xff1a;切到git视图去pull&#xff0c;然后切回java视图&#xff0c;再Team->switch to&#xff0c;就能找到了 二、在师傅的环境中能successful&#xff0c;在我的环境中却是failed 解决方法&#xff1a;eclipse-&g…

Javascript - prototype、__proto__、constructor

最近看了很多文章&#xff0c;想要更通透的搞懂JS中的prototype、__proto__与constructor属性&#xff0c;从各个博主的文章里摘取了我认为可以有助于理解的一些内容&#xff0c;希望自己能够掌握好这一重要知识点的同时也帮助到大家&#xff0c;具体内容请见下文。 &#xff0…

DOS下读取4GB内存

好文章我收集下起来 CPU上电后&#xff0c;从ROM 中的BIOS开始运行。 BIOS是处在内存的最顶端64KB&#xff08;FFFF0000H&#xff09;&#xff0c;还是1MB之下的64KB&#xff08;F0000H&#xff09;处呢&#xff1f;事实上&#xff0c;BIOS在这两个地方都同时出现。 在保护模式…

7纳米duv和euv_要超车台积电 三星宣布采用EUV技术7纳米制程完成验证

在晶圆代工市场&#xff0c;台积电与三星的竞争始终是大家关心的戏码。三星虽然有高通等VIP客户&#xff0c;但在7纳米制程节点&#xff0c;高通预计会转投台积电&#xff0c;三星要想受更多客户的青睐&#xff0c;只能从制程技术着手了。这也是三星跳过非EUV技术的7纳米制程&a…

HDU 1711 Number Sequence(KMP算法)

题目链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1711 Number Sequence Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15548 Accepted Submission(s): 6836Problem DescriptionGiven two s…

分享45款高质量的免费(X)HTML/CSS模板

当你需要在短时间内设计出一个网站的时候&#xff0c;网站模板就非常有用了。这也就是为什么这些设计模板已成为设计领域的最新趋势的原因。在这篇文章中&#xff0c;收集了各式各样的网站模板&#xff0c;您可以免费下载使用&#xff0c;希望这些设计模板不仅带给您灵感&#…

运维开发笔记整理-前后端分离

运维开发笔记整理-前后端分离 作者&#xff1a;尹正杰 版权声明&#xff1a;原创作品&#xff0c;谢绝转载&#xff01;否则将追究法律责任。 一.为什么要进行前后端分离 1>.pc, app, pad多端适应 2>.SPA开发式的流行&#xff08;单页Web应用&#xff08;single page we…

初识mysql数据字段属性_MySQL数据库~~~~初识、基础数据类型

一 数据库初识1.1 什么是数据库数据库(DataBase,简称DB),简而言之可视为电子化的文件柜----存储电子文件的处所,用户可以对文件中的数据运行新增,截取,更新,删除等操作. 所谓数据库是以一定方式储存在一起,能予多个用户 共享,具有尽可能小的冗余度,与应用程序彼此独立的数据集合…

WinForm导出文件,你懂的……

好久没有写文章了&#xff0c;下面把自己最近程序中用到的一个小小的导出文件的方法给在家分享一下&#xff0c;欢迎大家来排砖&#xff0c;谢谢~不说废话了&#xff0c;直接上代码&#xff1a; 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; …

PL/SQL第五章 Order by排序

1 -- 排序2 -- 1、列明排序3 -- 2、别名排序4 -- 3、列位置排序&#xff08;当使用union,union all,intersect,minus集合操作&#xff0c;列明不同&#xff0c;但希望排序&#xff09;5 SELECT deptno,dname FROM dept UNION6 SELECT empno,ename FROM emp7 ORDER BY 1 DESC;8 …

想转行学python过来人提醒大家几点

因为目前python非常火&#xff0c;应用也非常广泛&#xff0c;是目前最火的行业之一&#xff0c;竞争很大&#xff0c;工资很高&#xff0c;未来发展也极好。 首先告诉你&#xff0c;零基础学习python难度还是有的&#xff0c;python的专业程度本身就不简单&#xff0c;学习这事…

mysql答题表设计_PHP+MYSQL问答系统中的提问和回答的表怎么设计

展开全部PHPMYSQL 的问答系32313133353236313431303231363533e78988e69d8331333337396236统的设计与实现&#xff0c;问答系统简而言之 就是一个网上交流系统&#xff0c;针对学校这个特定环境&#xff0c;以学生和老师为主体&#xff0c;以实验室信息交流为话题而建立起的一个…

Android实时获取音量(单位:分贝)

基础知识 度量声音强度&#xff0c;大家最熟悉的单位就是分贝&#xff08;decibel&#xff0c;缩写为dB&#xff09;。这是一个无纲量的相对单位&#xff0c;计算公式如下&#xff1a; 分子是测量值的声压&#xff0c;分母是参考值的声压&#xff08;20微帕&#xff0c;人类所能…

排序算法 - 堆排序

堆排序是指利用堆这种数据结构所设计的一种排序算法。 类型&#xff1a;选择排序时间复杂度&#xff08;最坏&#xff09;&#xff1a;O(nlogn)时间复杂度&#xff08;最好&#xff09;&#xff1a;O(nlogn)时间复杂度&#xff08;平均&#xff09;&#xff1a;O(nlogn)空间复杂…

textContent与innerText的不同(转发)

textContent与innerText的不同 IE下有个innerText属性&#xff0c;FF下有个textContent属性。很多以前给IE写脚本的&#xff0c;在FF下找不到innerText属性&#xff0c;于是网上搜到的建议是用textContent来替代。反之给FF写脚本的也一样。 但是实际上&#xff0c;这里有个误解…

mysql插入性能_mysql 数据量大时插入和查询性能

现在mysql中有数据33.8w的数据&#xff0c;然后做查询和更新或插入操作&#xff0c;速度很慢&#xff0c;基本100条数据就要1.68s。好慢啊&#xff0c;我要测试一下&#xff0c;到底慢在哪&#xff1f;能不能提高点速度&#xff1f;参考一篇博文&#xff1a;http://blog.csdn.n…

Ext JS 4 笔记1

ExtJS4 引入了现在灰常流行的前端MVC。这在原本的3.3.1里面是没有的。原先项目里为了实现相对的MVC&#xff0c;自己写了一个controller和model &#xff0c;收集并且保持JS端的数据。所以呢&#xff0c;这时候的文档结构就完全不一样了。原本的结构更像是传统 C# winform &…

activemq 消息阻塞优化和消息确认机制优化

一、消息阻塞优化 1.activemq消费者在从待消费队列中获取消息是会先进行预读取&#xff0c;默认是1000条&#xff08;prefetch1000&#xff09;。这样很容易造成消息积压。 2.可以通过设置prefetch的默认值来调整预读取条数&#xff0c;java代码如下 //设置预读取为1ActiveMQPr…

iOS-查询数据库--指定数据表中的当前数据行的总数量

很多时候&#xff0c;我们在查询一个表的时候&#xff0c;不想得到里面的记录内容&#xff0c;只是想简单的得到符合查询条件的记录条数。 FMDB中有一个很简单的方法就可以实现&#xff0c;见下面的代码实例&#xff1a; #import "FMdatabase.h" (int)numberOfCurre…

mysql 判断日期是否在某范围内_判断时间是否在某个区间内

private bool IsInTimeInterval(DateTime time, DateTime startTime, DateTime endTime) {//判断时间段开始时间是否小于时间段结束时间,如果不是就交换 if (startTime > endTime) {DateTime tempTime = startTime; startTime = endTime; endTime = tempTime; } //获取以公…

数据库索引-基本知识

为什么80%的码农都做不了架构师&#xff1f;>>> 数据库索引--基本知识 有许多因素会影响数据库性能。最明显的是数据量&#xff1a;您拥有的数据越多&#xff0c;数据库的速度就越慢。虽然有很多方法可以解决性能问题&#xff0c;但主要的解决方案是正确索引数据库…

Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception

依赖注入容器Unity: Unity的构造类似于Castle中的IOC&#xff08;控制反转 或者叫依赖注入&#xff09;容器,我们使用抽象接口来隔离使用者和具体实现之间的依赖关系&#xff0c;但是不管再怎么抽象&#xff0c;最终还是要创建具体实现类的实例&#xff0c;这种创建具体实现类的…

pycharm 使用小结

1.pycharm 自动换行,显示行号,缩进向导 在代码右侧右键 2.自动注释/取消注释 ctrl /转载于:https://www.cnblogs.com/xuesu/p/4755086.html

golang socket读写同时_epoll在Golang的应用

使用Golang可以轻松地为每一个TCP连接创建一个协程去服务而不用担心性能问题&#xff0c;这是因为Go内部使用goroutine结合IO多路复用实现了一个“异步”的IO模型&#xff0c;这使得开发者不用过多的关注底层&#xff0c;而只需要按照需求编写上层业务逻辑。这种异步的IO是如何…

HTTP 2.0与OkHttp

HTTP 2.0是对1.x的扩展而非替代&#xff0c;之所以是“2.0”&#xff0c;是因为它改变了客户端与服务器之间交换数据的方式。HTTP 2.0增加了新的二进制分帧数据层&#xff0c;而这一层并不兼容之前的HTTP 1.x服务器及客户端——是谓2.0。  在正式介绍HTTP 2.0之前&#xff0c;…

根据“坐标”生成趋势图

数据库环境&#xff1a;SQL SERVER 2008R2 有一“坐标”表t&#xff0c;表结构如下&#xff1a; id int&#xff0c; num int 字段id是序号&#xff0c;递增且连续&#xff0c;字段num是数值类型。id可以看成是坐标轴的横轴&#xff0c;num则跟纵轴有关系&…

Winform程序怎么降低占用的内存?

1 Winform程序怎么降低占用的内存&#xff1f;winform程序占用的内存数一直居高不下&#xff0c;提供给用户的手册中说明内存不能大于50MB,但是每次运行的时候&#xff0c;内存都会飙高到100多MB. 2 3 后来终于发现了一个方法&#xff0c;可以解决这个问题&#xff1a; …