Le cœur et l'essence de la programmation concurrente

Prenez l'habitude d'écrire ensemble ! C'est le 15ème jour de ma participation au "Nuggets Daily New Plan·April Update Challenge", cliquez pour voir les détails de l'événement

Cette série de colonnes Colonne de programmation concurrente Java - Colonne de Yuanhao 875 - Nuggets (juejin.cn)

image.png

avant-propos

La programmation concurrente n'est pas une discipline relativement indépendante, mais une discipline complète, qui implique beaucoup de points de connaissance.Cet article parlera d'abord du cœur et de l'essence de la programmation concurrente.

texte

Quels que soient les points de connaissance à apprendre, le plus tabou est "les aveugles touchent l'éléphant". Il existe de très bonnes méthodes d'apprentissage appelées "sauter et voir le panorama" et "plonger et voir l'essence". Bien qu'il y ait beaucoup des connaissances en programmation concurrente, elle peut être résumée en 3 problèmes fondamentaux : la division du travail, la synchronisation et l'exclusion mutuelle .

répartition du travail

La soi-disant division du travail est similaire au fait que vous êtes un chef de projet en réalité. Vous devez organiser et mener à bien un projet, vous devez diviser ces tâches et organiser le personnel approprié pour les faire ; dans la programmation simultanée, les employés sont équivalent aux threads, et vous devez allouer raisonnablement les tâches aux threads, car cela déterminera directement les performances des programmes concurrents.

Il existe de nombreux SDK avec division du travail en Java. Par exemple, Executor et Fork/Join sont essentiellement une méthode de division du travail, y compris le modèle de conception producteur-consommateur. Ces idées expliquent comment répartir une tâche de manière raisonnable .

Synchroniser

Une fois le travail divisé, il est exécuté. Dans l'exécution du projet, il existe des dépendances entre les tâches. Par exemple, une fois l'examen des besoins terminé, le développeur doit commencer à coder. Comment notifier le démarrage de la tâche de suivi ? Dans dans la vraie vie, cela dépend de la communication. La collaboration est une chose très importante.

En programmation concurrente, il fait principalement référence à la coopération entre les threads, qui n'est pas différente de la vie réelle, c'est-à-dire, lorsqu'un thread termine l'exécution d'une tâche, comment notifier le thread des tâches suivantes à démarrer .

协作一般和分工是相关的,比如Future可以发起一个异步调用,当主线程通过get()方法获取结果时,主线程就会等待,当异步执行结果返回时,get()方法就自动返回了,这个主线程和异步线程之间的协作,Future工具类帮我做好了。

在工作中线程协作问题,一般可以归纳为:当某个条件不满足时,线程需要等待,当某个条件满足时,线程需要被唤醒执行。比如在生产者-消费者模型中,当队列满时,生产者线程等待,当队列不满时,生产者线程需要被唤醒执行;当队列为空时,消费者线程等待,当队列不为空时,消费者线程需要被唤醒执行。

互斥

分工、同步主要是强调性能,但在并发程序中还有一部分是关于正确性的,专业术语叫做"线程安全"。

在并发程序中,当多个线程同时访问一个共享变量时,结果是不确定的,而导致不确定的主要源头是可见性问题、有序性问题和原子性问题,为了解决这3个问题,Java语言引入了内存模型,内存模型提供了一系列的规则,利用这些规则,可以避免可见性、有序性问题,但是还不足以解决线程安全问题,解决线程安全的核心方案还是互斥。

互斥就是在同一时刻,只允许一个线程访问共享变量

实现互斥的核心技术就是锁,Java中的synchronized、SDK中的各种Lock都可以解决互斥问题,但是同时也带来性能问题,这就要分情况、分场景进行优化,比如ReadWriteLock、StampedLock可以优化读多写少的场景,还可以使用原子类这种无锁的数据结构。

总结

现在已经"跳出来,看全景"了,我们可以理解并发编程的核心和本质了,接下来的文章我们会不断地"钻进去,看本质",来解析和印证。

Je suppose que tu aimes

Origine juejin.im/post/7086621565793599495
conseillé
Classement