Java多线程简析——Synchronized(同步锁)、Lock以及线程池

Synchronized 同步锁详解 Synchronized是JAVA的关键字,是基于JVM层面的独占式的悲观锁,同时也属于可重入锁经常来用于解决多个线程之间访问访问资源的同步性,保证在同一时刻只有一个线程访问这个资源。 阅读详情

Java多线程简析——Synchronized(同步锁)、Lock以及线程池

 

Java多线程

Java中,可运行的程序都是有一个或多个进程组成。进程则是由多个线程组成的。

最简单的一个进程,会包括mian线程以及GC线程。

线程的状态

线程状态由以下一张网上图片来说明:

在图中,红框标识的部分方法,可以认为已过时,不再使用。

(1)wait、notify、notifyAll是线程中通信可以使用的方法。线程中调用了wait方法,则进入阻塞状态,只有等另一个线程调用与wait同一个对象的notify方法。这里有个特殊的地方,调用wait或者notify,前提是需要获取锁,也就是说,需要在同步块中做以上操作。

(2)join方法。该方法主要作用是在该线程中的run方法结束后,才往下执行。如以下代码:

 


 
  1. package com.thread.simple;

  2.  
  3. public class ThreadJoin {

  4.  
  5.  
  6. public static void main(String[] args) {

  7.  
  8. Thread thread= new Thread(new Runnable() {

  9.  
  10. @Override

  11. public void run() {

  12. System.err.println("线程"+Thread.currentThread().getId()+" 打印信息");

  13. }

  14. });

  15. thread.start();

  16.  
  17. try {

  18. thread.join();

  19. } catch (InterruptedException e) {

  20. // TODO Auto-generated catch block

  21. e.printStackTrace();

  22. }

  23.  
  24. System.err.println("主线程打印信息");

  25.  
  26. }

  27.  
  28. }

该方法显示的信息是:

 

线程8 打印信息

主线程打印信息
 

如果去掉其中的join方法,则显示如下:

主线程打印信息
线程8 打印信息

(3)yield方法。这个是线程本身的调度方法,使用时你可以在run方法执行完毕时,调用该方法,告知你已可以出让内存资源。

其他的线程方法,基本都会在日常中用到,如start、run、sleep,这里就不再介绍。

Synchronized(同步锁)

在Java中使用多线程,你就不能绕过同步锁这个概念。这在多线程中是十分重要的。

在Java多线程的使用中,你必然会遇到一个问题:多个线程共享一个或者一组资源,这资源包括内存、文件等。

很常见的一个例子是,张三在银行账户存有9999元,经过多次的取100,存100后,账户还有多少钱?

看代码:

以下表示账户信息:

 


 
  1. package com.thread.simple;

  2.  
  3. import java.sql.Time;

  4. import java.util.concurrent.TimeUnit;

  5.  
  6. public class Account {

  7.  
  8. private String name;

  9. private float amt;

  10. public Account(String name,float amt) {

  11. this.name=name;

  12. this.amt=amt;

  13. }

  14.  
  15. public void increaseAmt(float increaseAmt){

  16. try {

  17. TimeUnit.SECONDS.sleep(1);

  18. } catch (InterruptedException e) {

  19. // TODO Auto-generated catch block

  20. e.printStackTrace();

  21. }

  22. amt+=increaseAmt;

  23. }

  24.  
  25. public void decreaseAmt(float decreaseAmt){

  26. try {

  27. TimeUnit.SECONDS.sleep(1);

  28. } catch (InterruptedException e) {

  29. // TODO Auto-generated catch block

  30. e.printStackTrace();

  31. }

  32. amt-=decreaseAmt;

  33. }

  34.  
  35. public void printMsg(){

  36. System.out.println(name+"账户现有金额为:"+amt);

  37. }

  38. }


以下是我们操作账户的方法:

 

 


 
  1. <span style="white-space:pre"> </span>final int NUM=100;

  2.  
  3. Thread[] threads=new Thread[NUM];

  4. for(int i=0;i<NUM;i++){

  5. if(threads[i]==null){

  6. threads[i]=new Thread(new Runnable() {

  7.  
  8. @Override

  9. public void run() {

  10. account.increaseAmt(100f);

  11. account.decreaseAmt(100f);

  12. }

  13. });

  14. threads[i].start();

  15. }

  16. }

  17.  
  18. for(int i=0;i<NUM;i++){

  19. try {

  20. threads[i].join();

  21. } catch (InterruptedException e) {

  22. // TODO Auto-generated catch block

  23. e.printStackTrace();

  24. }

  25. }

  26.  
  27. account.printMsg();

你会发现,每次打印出来的账户余额都不一定是一样的。这就是同步锁的必要性。

 

java中,提供了多种使用同步锁的方式。

(1)对动态方法的修饰。

作用的是调用该方法的对象(或者说对象引用)。

 

public synchronized void doSomething(){}

 

  ( 2)  对代码块的修饰。

作用的是调用该方法的对象(或者说对象引用)。

 


 
  1. public void increaseAmt(float increaseAmt){

  2.  
  3. try {

  4. TimeUnit.SECONDS.sleep(1);

  5. } catch (InterruptedException e) {

  6. // TODO Auto-generated catch block

  7. e.printStackTrace();

  8. }

  9. synchronized (this) {

  10. System.out.println(this);

  11. amt+=increaseAmt;

  12. }

  13. }

 

(3)对静态方法的修饰。

 

作用的是静态方法所在类的所有对象(或者说对象引用)。

 


 
  1. public synchronized static void increaseAmt(float increaseAmt){

  2. try {

  3. TimeUnit.SECONDS.sleep(1);

  4. } catch (InterruptedException e) {

  5. // TODO Auto-generated catch block

  6. e.printStackTrace();

  7. }

  8. amt+=increaseAmt;

  9. }

 

 

(4)对类的修饰。

 

作用的是静态方法所在类的所有对象(或者说对象引用)。

 


 
  1. synchronized (AccountSynchronizedClass.class) {

  2. amt-=decreaseAmt;

  3. }


以修饰代码块的方式为例,我们重新运行以上代码后,得到了正确的结果。代码如下:

 

 


 
  1. package com.thread.simple;

  2.  
  3. import java.util.concurrent.TimeUnit;

  4. /**

  5. * Synchronized 代码块

  6. * @author 战国

  7. *

  8. */

  9. public class AccountSynchronizedBlock {

  10.  
  11. private String name;

  12. private float amt;

  13. public AccountSynchronizedBlock(String name,float amt) {

  14. this.name=name;

  15. this.amt=amt;

  16. }

  17.  
  18. public void increaseAmt(float increaseAmt){

  19.  
  20. try {

  21. TimeUnit.SECONDS.sleep(1);

  22. } catch (InterruptedException e) {

  23. // TODO Auto-generated catch block

  24. e.printStackTrace();

  25. }

  26. synchronized (this) {

  27. System.out.println(this);

  28. amt+=increaseAmt;

  29. }

  30. }

  31.  
  32. public void decreaseAmt(float decreaseAmt){

  33. try {

  34. TimeUnit.SECONDS.sleep(1);

  35. } catch (InterruptedException e) {

  36. // TODO Auto-generated catch block

  37. e.printStackTrace();

  38. }

  39. synchronized (this) {

  40. System.out.println(this);

  41. amt-=decreaseAmt;

  42. }

  43.  
  44. }

  45.  
  46. public void printMsg(){

  47. System.out.println(name+"账户现有金额为:"+amt);

  48. }

  49. }

 

 


 
  1. //多线程synchronized修饰代码块 ,每次计算的值都一样

  2.  
  3. final AccountSynchronizedBlock account=new AccountSynchronizedBlock("张三", 9999.0f);

  4. final int NUM=50;

  5.  
  6. Thread[] threads=new Thread[NUM];

  7. for(int i=0;i<NUM;i++){

  8. if(threads[i]==null){

  9. threads[i]=new Thread(new Runnable() {

  10.  
  11. @Override

  12. public void run() {

  13. account.increaseAmt(100f);

  14. account.decreaseAmt(100f);

  15. }

  16. });

  17. threads[i].start();

  18. }

  19. }

  20.  
  21. for(int i=0;i<NUM;i++){

  22. try {

  23. threads[i].join();

  24. } catch (InterruptedException e) {

  25. // TODO Auto-generated catch block

  26. e.printStackTrace();

  27. }

  28. }

  29. account.printMsg();


以上是同步锁的简单说明。

在JDK5中,Java又引入了一个相似的概念Lock,也就是锁。功能与synchronized是类似的。

Lock

Lock对比synchronized有高手总结的差异如下:

 

总结来说,Lock和synchronized有以下几点不同:

  1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;

  2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;

  3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;

  4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。

  5)Lock可以提高多个线程进行读操作的效率。

  在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。

(参考http://www.cnblogs.com/dolphin0520/p/3923167.html)。

Lock的操作与synchronized相比,灵活性更高,而且Lock提供多种方式获取锁,有Lock、ReadWriteLock接口,以及实现这两个接口的ReentrantLock类、ReentrantReadWriteLock类。

对Lock的简单操作代码如下:

 


 
  1. package com.thread.simple;

  2.  
  3. import java.util.ArrayList;

  4. import java.util.List;

  5. import java.util.concurrent.locks.Lock;

  6. import java.util.concurrent.locks.ReadWriteLock;

  7. import java.util.concurrent.locks.ReentrantLock;

  8. import java.util.concurrent.locks.ReentrantReadWriteLock;

  9.  
  10. public class LockImp {

  11.  
  12.  
  13. private Lock lock=new ReentrantLock();

  14. private ReadWriteLock rwLock=new ReentrantReadWriteLock();

  15.  
  16. private List<Integer> list=new ArrayList<Integer>();

  17.  
  18. public void doReentrantLock(Thread thread){

  19. lock.lock();

  20. System.out.println(thread.getName()+"获取锁");

  21. try {

  22. for(int i=0;i<10;i++){

  23. list.add(i);

  24. }

  25. } catch (Exception e) {

  26.  
  27. }finally{

  28. lock.unlock();

  29. System.out.println(thread.getName()+"释放锁");

  30. }

  31.  
  32. }

  33. public void doReentrantReadLock(Thread thread){

  34. rwLock.readLock().lock();

  35. System.out.println(thread.getName()+"获取读锁");

  36. try {

  37. for(int i=0;i<10;i++){

  38. list.add(i);

  39. }

  40. } catch (Exception e) {

  41.  
  42. }finally{

  43. rwLock.readLock().unlock();

  44. System.out.println(thread.getName()+"释放读锁");

  45. }

  46.  
  47. }

  48. public void doReentrantWriteLock(Thread thread){

  49. rwLock.writeLock().lock();

  50. System.out.println(thread.getName()+"获取写锁");

  51. try {

  52. for(int i=0;i<10;i++){

  53. list.add(i);

  54. }

  55. } catch (Exception e) {

  56.  
  57. }finally{

  58. rwLock.writeLock().unlock();

  59. System.out.println(thread.getName()+"释放写锁");

  60. }

  61.  
  62. }

  63.  
  64.  
  65.  
  66. /**

  67. * @param args

  68. */

  69. public static void main(String[] args) {

  70.  
  71. final LockImp lockImp=new LockImp();

  72.  
  73. final Thread thread1=new Thread();

  74. final Thread thread2=new Thread();

  75. final Thread thread3=new Thread();

  76.  
  77. new Thread(new Runnable() {

  78.  
  79. @Override

  80. public void run() {

  81. lockImp.doReentrantLock(thread1);

  82. }

  83. }).start();

  84.  
  85. new Thread(new Runnable() {

  86.  
  87. @Override

  88. public void run() {

  89. lockImp.doReentrantLock(thread2);

  90. }

  91. }).start();

  92.  
  93. new Thread(new Runnable() {

  94.  
  95. @Override

  96. public void run() {

  97. lockImp.doReentrantLock(thread3);

  98. }

  99. }).start();

  100.  
  101.  
  102. lockImp.doReentrantReadLock(thread1);

  103. lockImp.doReentrantReadLock(thread2);

  104. lockImp.doReentrantReadLock(thread3);

  105.  
  106. lockImp.doReentrantWriteLock(thread1);

  107. lockImp.doReentrantWriteLock(thread2);

  108. lockImp.doReentrantWriteLock(thread3);

  109. }

  110.  
  111. }

  112.  


Lock的使用中,务必需要lock、unlock同时使用,避免死锁。

 

 

线程池的使用

为什么使用线程池?

 

因为使用它有好处:(1)在界面上,简化了写法,代码更简洁(2)对程序中的线程可以进行适度的管理(3)有效较低了多个线程的内存占有率等。

这是一篇讲述线程池非常好的文章:http://www.cnblogs.com/dolphin0520/p/3932921.html

如果对线程池有不了解的同学,可以参考链接中的文章,讲的深入浅出。

在这里只是简单的封装一个线程池的工具类,仅供参考:

 


 
  1. package com.thread.simple;

  2.  
  3. import java.util.concurrent.ExecutorService;

  4. import java.util.concurrent.Executors;

  5.  
  6. public class ThreadPoolUtil {

  7.  
  8. private volatile static ThreadPoolUtil instance;

  9. private ThreadPoolUtil(){}

  10. private static ExecutorService threadPool;

  11.  
  12.  
  13. public static ThreadPoolUtil getInstance(){

  14. if(instance==null){

  15. synchronized (ThreadPoolUtil.class) {

  16. instance=new ThreadPoolUtil();

  17. threadPool=Executors.newCachedThreadPool();

  18. }

  19. }

  20. return instance;

  21. }

  22.  
  23. public void excute(Runnable runnable){

  24. threadPool.execute(runnable);

  25. }

  26.  
  27. public void shutdown(){

  28. threadPool.shutdown();

  29. }

  30.  
  31. public boolean isActive(){

  32. if(threadPool.isTerminated()){

  33. return false;

  34. }

  35. return true;

  36. }

  37. }

 

Java中的同步与锁机制详解 线程饥饿是指一个线程因为竞争资源而长时间得不到执行的现象。在某些情况下,由于调度策略或者其他因素,一些线程可能长时间无法获得所需资源,导致这些线程一直处于等待状态,无法继续执行。这种现象称为线程饥饿。以一个简单的银行排队场景为例。假设银行有两个窗口(资源),分别由两个线程( 阅读详情

相关推荐

JAVA多线程之并发与同步,Lock与Syncronized

说到线程,就不得不先说线程和进程的关系。进程是系统的执行单位,一般一个应用程序即是一个进程,程序启动时系统默认有一个主线程,即是UI线程,我们知道不能做耗时任务,否则ANR程序无响应。这时需要借助子线程实现,即多线程。由于线程是系统CPU的最小单位,用多线程其实就是为了更好的利用cpu的资源。一、多线程创建方式//线程休眠1000毫秒,sleep使线程进入Block状态,并释放资源xx.start();//启动线程,run函数运行@Override@Override。

csdn_aiyang的博客 2万+

Java之同步锁

Java支持同步锁(synchronization lock)机制以及可重入锁(re-entrant lock)机制,本章节主要描述同步锁的机制。

wys的专栏 1万+

java多线程三种实现方式和线程池使用详解

多线程的三种实现方式 继承Thread类 实现Runnable接口 实现Callable接口 线程安全问题 卖车票案例 解决线程安全 同步代码块 同步方法 同步锁(Lock锁) 线程池的使用 Excutors创建多线程 ExecutorService创建多线程(常用子类ThreadPoolExecutor) 多线程中workQueue任务队列集中使用类型 拒绝策略 ThreadFactory自定义线程创建 ThreadPoolExecutor扩展 线程池线程数量

张刚的博客 889

JAVA 同步锁

同一个订单才加同步锁,不同订单可并行。

cimbala的博客 3160

vue3 web项目引入高拍仪

高拍仪的引入步骤就两步,安装SDK,然后根据官网的api进行开发。根据自己需要的功能,请求对应的接口。

qq_42480170的博客 4116

别再为格式发愁:safetensors转GGUF的三种高效方法及Ollama集成对比

本文详细介绍了将safetensors格式转换为GGUF格式的三种高效方法,包括llama.cpp原生转换、GGUF官方工具链和Transformers中转方案,并对比了它们在Ollama集成中的表现。文章还提供了实际项目中的踩坑经验和性能调优建议,帮助开发者快速掌握模型转换技术。

weixin_42651281的博客 640

Java并发: 锁和同步

前面我们通过LockSupport实现了一个简单的独占锁FIFOMutex,但是功能比较简易。Java内部通过了一个类似的实现,只需要覆写少数方法就能创建一个功能强大的锁,AbstractQueueSynchronizer类似于FIFOMutex,AQS也维护了一个内部状态state,将等待锁的线程通过一个CLH队列保存,额外提供ConditionObject对象,支持基于条件的等待还唤醒,同时它还支持共享锁。

你若盛开,清风自来 1946

攻防世界 Crypto 新手练习区 1-12 全详解

本篇是攻防世界 Crypto 新手练习区的全解

闵行小鱼塘 3733

java Synchronized 多线程同步

如下代码:public class SyncClass{synchronized void syncMethod1(){}synchronized void syncMethod2(){}void syncMethod3(){synchronized(this)}void syncMethod4(){synchronized(obj){}}synchronized static void syncMethod5(){}synchronized Static void syncMethod6(){}}同一实例

kufeiyun的专栏 1222

Supermind量化实战:我如何给双均线策略加上“止损”和“仓位管理”,让回测收益更稳健

本文详细介绍了如何在Supermind平台上为双均线策略添加止损和仓位管理模块,以提升量化交易的稳健性。通过Python实现动态止损和智能仓位管理,策略的年化收益率从12.3%提升至15.8%,最大回撤从58.7%降至22.4%,Sharpe比率显著提高。这些实战技巧适用于量化交易爱好者,帮助他们在黑天鹅行情中保持收益稳定。

weixin_42567752的博客 363

知识图谱初步学习(一)——本体+Protege新手学习

文章目录前言(本体详解)1.本体概念2.本体分类3.本体组成4.本体构建方法一、protege简介二、软件使用步骤1.安装2.使用三、问题解决方案汇总 前言(本体详解) 在开始学习知识图谱的过程中,首先就是要了解什么是本体(ontology)。 1.本体概念 本体的概念最初源自于哲学领域,在哲学中的定义为“对世界上客观事物的系统描述,即存在论”。哲学中的本体关心的是客观现实的抽象本质。而在计算机领域,本体是可以在语义的层次上来对知识进行描述,可以看做是某一个领域知识的通用模型。 本体是从客观世界中抽象出来

qq_43654669的博客 3万+

JAVA多线程和线程池

目录 1、线程状态 (1) 新建状态 (2) 就绪状态 (3) 运行状态 (4) 阻塞状态 (5) 死亡状态 2、线程优先级 3、同步工具synchronized、wait、notify 4、创建线程 (1) 实现 Runnable 接口 (2) 继承 Thread 类 (3) 通过 Callable 和 Future 创建线程 5、三种创建方式的区别 6、线程池 (...

itakyubi的博客 7029

瑞芯微RK3588系统重装实战:从Windows到Linux的完整烧录指南

本文提供了一份详尽的瑞芯微RK3588开发板系统重装实战指南,涵盖从Windows到Linux双平台的完整烧录流程。针对RK3588芯片特性,详细解析了驱动安装、工具使用、固件烧录步骤及常见问题排错,旨在帮助开发者高效、安全地完成系统切换与部署,快速投入AI推理与边缘计算等应用开发。

weixin_29164185的博客 360

Java中的线程、多线程、线程状态、同步锁、线程通信

一般来说,所有等待的线程会按照顺序进行排列,如果现在使用了 notify()方法的话,则会唤醒第一个等待的线程执行,而如果使用了 notifyAll()方法,则会唤醒所有的等待线程,哪个线程的优先级高,哪个线程就有可能先执行。就是主线程,多个线程同时执行就是多线程,线程池就是把准备好的线程放到线程池里,如果处理请 求需要调用线程的时候,就从线程池里去调用,用完以后再放回到线程池里,这样就防止高 并发节省资源。而 ThreadLocal 是为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并。

Gfggygucg的博客 792

智联招聘Python岗位数据采集:基于API请求的校园招聘信息爬取实战

本项目开发了一个智联招聘Python岗位校园招聘数据采集系统,采用requests库直接调用API接口获取结构化数据。系统通过分析API接口结构,配置完整的请求头、Cookie和身份验证参数,实现了10页数据的批量采集。采集内容包括工作名称、薪资范围、企业信息等10个关键字段,并存储为Excel格式。项目严格遵守网络爬虫规范,合理控制请求频率,数据仅用于技术学习和就业分析。技术实现涉及API逆向工程、JSON数据处理、防御性编程等核心技能,为学生职业规划和教育机构教学改革提供数据支持。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 626

PowerPMAC配置EtherCAT设备

本文详细介绍了在PowerPMAC IDE环境下配置EtherCAT伺服电机的完整流程。主要内容包括:准备工作(连接硬件和获取ESI文件)、通过ESI管理器加载配置文件、网络扫描识别从站设备、变量映射(定义输入输出位置参数)、激活EtherCAT通讯(验证状态字和实际位置)以及相关参数说明。文章还概述了主站配置的8个方面和从站配置的7个选项,重点说明了PDO映射和变量分配机制,为伺服电机的EtherCAT通信配置提供了系统指导。

mahuliang321的博客 971

Java--多线程之synchronized和lock;死锁(四)

在了解synchronized之前,我们先看一个线程不安全的示例如一个账户中有1万块钱,两个人同时取钱,会导致余额不对,或者取的钱比账户中金额还多输出如下t1和t2线程分别在同一个总金额为1万的账户取款 5千,然余额还是5千,这就导致了多线程并发下数据不安全的情况。

MinggeQingchun的博客 1675

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Java经典面试题汇总(七)多线程

本篇总结的是Java多线程相关的面试题,后续会持续更新,希望我的分享可以帮助到正在备战面试的实习生或者已经工作的同行,如果发现错误还望大家多多包涵,不吝赐教,谢谢~ 1.并行和并发有什么区别? 并行:多个处理器或多核处理器同时处理多个任务。 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。 并发 = 两个队列和一台咖啡机。 并行 = 两个队列和两台咖啡机。 2. 线程和进程的区别? 一个程序下至少有一个进程,一个进程下至少有一个...

nbme的博客 6552

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

java中程序进程、线程、多线程,线程同步、synchronized、Lock锁总结

进程、线程、多线程,线程同步、synchronized、Lock锁一、进程&线程二、线程的创建方式1.Thread类概述构造方法创建线程方式2.Runnable接口创建方式好处3.Callable接口创建方式FutureTask对象4.Runnable与Callable5.线程池三、线程安全&同步1.同步同步锁机制注意同步的范围释放锁操作不会释放锁操作2.synchronized3.死锁4.Lock锁5.synchronized与Lock锁比较6.线程通信四、线程池1.概述2.好处3.四种线

A-Itfuture的博客 1137

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

学习Java第三十天--多线程之线程池和同步锁

线程池、Callable接口、Future接口、Lock接口、同步锁的使用方法14.4 线程池14.4.1 线程池概念14.4.2 线程池原理14.4.3 获取线程池14.4.4 Callable接口14.4.5 Future接口14.4.6 线程的同步14.4.7 线程的异步14.4.8 Lock接口14.4.8 重入锁14.4.9 读写锁14.4.10 ReentrantReadWriteLo...

X池鱼 474

多线程、同步锁、定时器

在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步。通信是指线程之间以如何来交换信息。一般线程之间的通信机制有两种:共享内存和消息传递。

qq_58095042的博客 954
上一篇: 高并发服务器
下一篇: 金融行业密钥详解
TuxedoLinux
博客等级 码龄9年 268粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值