-
Notifications
You must be signed in to change notification settings - Fork 0
/
atomare-datentypen.html
18 lines (17 loc) · 9.63 KB
/
atomare-datentypen.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html><html lang="de-ch"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Atomare Datentypen - Finecloud</title><meta name="description" content="Das Problem beim inkrementieren von einer zentralen int-Variabel mit mehreren Threads ist, dass diese sich bekanntlich überschreiben. Davon handelt der vorherige Blogpost. Die einzige Lösung hierfür ist, dass man statt der primitiven Objekt int-Klasse die Klasse java.util.concurrent.atomic.AtomicInteger zu verwenden. Der einzige Zweck dieser Klasse ist,…"><meta name="generator" content="Publii Open-Source CMS for Static Site"><link rel="stylesheet" href="https://www.finecloud.ch/media/plugins/syntaxHighlighter/prism-black.css"><link rel="canonical" href="https://www.finecloud.ch/atomare-datentypen.html"><link rel="alternate" type="application/atom+xml" href="https://www.finecloud.ch/feed.xml"><link rel="alternate" type="application/json" href="https://www.finecloud.ch/feed.json"><meta property="og:title" content="Atomare Datentypen"><meta property="og:site_name" content="Finecloud"><meta property="og:description" content="Das Problem beim inkrementieren von einer zentralen int-Variabel mit mehreren Threads ist, dass diese sich bekanntlich überschreiben. Davon handelt der vorherige Blogpost. Die einzige Lösung hierfür ist, dass man statt der primitiven Objekt int-Klasse die Klasse java.util.concurrent.atomic.AtomicInteger zu verwenden. Der einzige Zweck dieser Klasse ist,…"><meta property="og:url" content="https://www.finecloud.ch/atomare-datentypen.html"><meta property="og:type" content="article"><link rel="shortcut icon" href="https://www.finecloud.ch/media/website/finecloud.png" type="image/png"><link rel="stylesheet" href="https://www.finecloud.ch/assets/css/style.css?v=39da73365516a098a9b73b721fc970e2"><script type="application/ld+json">{"@context":"http://schema.org","@type":"Article","mainEntityOfPage":{"@type":"WebPage","@id":"https://www.finecloud.ch/atomare-datentypen.html"},"headline":"Atomare Datentypen","datePublished":"2022-06-18T14:27","dateModified":"2022-06-20T07:08","description":"Das Problem beim inkrementieren von einer zentralen int-Variabel mit mehreren Threads ist, dass diese sich bekanntlich überschreiben. Davon handelt der vorherige Blogpost. Die einzige Lösung hierfür ist, dass man statt der primitiven Objekt int-Klasse die Klasse java.util.concurrent.atomic.AtomicInteger zu verwenden. Der einzige Zweck dieser Klasse ist,…","author":{"@type":"Person","name":"Finecloud","url":"https://www.finecloud.ch/authors/finecloud/"},"publisher":{"@type":"Organization","name":"Finecloud"}}</script><meta name="google-site-verification" content="seFY9U12uiEq5U3_MyZiX6XWzk0AVFl9zITr2ZKsytY"></head><body><div class="site-container"><header class="top" id="js-header"><a class="logo" href="https://www.finecloud.ch/">Finecloud</a><nav class="navbar js-navbar"><button class="navbar__toggle js-toggle" aria-label="Menu" aria-haspopup="true" aria-expanded="false"><span class="navbar__toggle-box"><span class="navbar__toggle-inner">Menu</span></span></button><ul class="navbar__menu"><li><a href="https://www.finecloud.ch/" target="_self">Blog</a></li><li><a href="https://www.finecloud.ch/tags/" target="_self">Tags</a></li></ul></nav><div class="search"><div class="search__overlay js-search-overlay"><div class="search__overlay-inner"><form action="https://www.finecloud.ch/search.html" class="search__form"><input class="search__input js-search-input" type="search" name="q" placeholder="search..." aria-label="search..." autofocus="autofocus"></form><button class="search__close js-search-close" aria-label="Close">Close</button></div></div><button class="search__btn js-search-btn" aria-label="Search"><svg role="presentation" focusable="false"><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#search"/></svg></button></div></header><main><article class="post"><div class="hero"><figure class="hero__image hero__image--overlay"><img src="https://www.finecloud.ch/media/website/download.jpg" srcset="https://www.finecloud.ch/media/website/responsive/download-xs.jpg 300w, https://www.finecloud.ch/media/website/responsive/download-sm.jpg 480w, https://www.finecloud.ch/media/website/responsive/download-md.jpg 768w, https://www.finecloud.ch/media/website/responsive/download-lg.jpg 1024w, https://www.finecloud.ch/media/website/responsive/download-xl.jpg 1360w, https://www.finecloud.ch/media/website/responsive/download-2xl.jpg 1600w" sizes="100vw" loading="eager" alt=""></figure><header class="hero__content"><div class="wrapper"><div class="post__meta"><time datetime="2022-06-18T14:27">Juni 18, 2022</time></div><h1>Atomare Datentypen</h1></div></header></div><div class="wrapper post__entry"><p>Das Problem beim inkrementieren von einer zentralen int-Variabel mit mehreren Threads ist, dass diese sich bekanntlich überschreiben. Davon handelt der vorherige <a href="https://www.finecloud.ch/multithreading.html">Blogpost</a>. Die einzige Lösung hierfür ist, dass man statt der primitiven Objekt int-Klasse die Klasse <em>java.util.concurrent.atomic.AtomicInteger</em> zu verwenden. Der einzige Zweck dieser Klasse ist, int-Operatoren atomar zu machen. Für diesen Zweck bietet sich die Methode <em>incrementAndGet</em> an, die dasselbe macht die der ++-Operator für int-primitive, aber garantiert atomar:</p><p><code>public class ThreadTest {</code><br><code> public AtomicInteger counter = new AtomicInteger();</code><br><br><code> public void run() {</code><br><code> Thread[] threads = new Thread[10];</code><br><code> for (int i = 0; i < 10; i++) {</code><br><code> threads[i] = new Thread(() -> {</code><br><code> for (int j = 0; j < 100; j++){</code><br><code> counter.incrementAndGet();</code><br><code> }</code><br><code> }, "Thread " + i);</code><br><code> threads[i].start();</code><br><code> }</code><br><code> //warten und ausgeben, genau wie vorher</code><br><code> }</code><br><code>}</code></p><p>Dieser Code zählt garantiert immer bis 1000. AtomicInteger stellt sicher, dass es niemals zu einer Unterbrechung zwischen Auslesen, Addieren und Zurückschreiben kommt, egal wieviele Threads darauf zugreifen.</p><p>Das bedeutet für alle anderen Threads, dass die warten müssen. Erst wenn der vorherige Thread die Methode <em>incrementAndGet</em> verlassen hat, kann der nächste Thread sie betreten.</p><p>Die anderen Methoden von AtomicInteger funktionieren auch nach diesem Prinzip:</p><ul><li><em>decrementAndGet</em> verringert den Wert um eins, entsprechend dem Operator --.</li><li><em>getAndIncrement</em> und <em>getAndDecrement</em> erhöhen/verringern den gespeicherten Wert ebenfalls, geben aber den alten Wert zurück. Diese Methoden entsprechen den nachgestellten Operatoren x++ und x--, die vorgenannten Methoden den vorangestellten Operatoren ++x und --x.</li><li><em>addAndGet</em> addiert den übergeben int-Wert zum gespeicherten Wert. Es gibt keine analoge Methode subtractAndGet, zum Subtrahieren muss man eine negative Zahl an <em>addAndGet</em> übergeben.</li><li><em>set</em> setzt einen neuen Wert und überschreibt den alten.</li><li><em>getAndSet</em> setzt einen neuen Wert und gibt den alten Wert zurück.</li><li><em>compareAndSet</em> nimmt zwei int-Parameter und setzt den zweiten als neuen Wert, wenn dem der erste dem aktuellen Wert entspricht.</li></ul><p>Dieselben Methoden bietet auch die Klasse AtomicLong, die Operationen auf einer long-Variablen atomar macht. Daneben gibt es die Klassen AtomicBoolean und AtomicReference, die für eine boolean-Variable bzw. für eine Objektvariable die Operationen getAndSet und compareAndSet anbieten.</p><p>Wenn man mehrere Variablen in einem gemeinsamen konsistenten Zustand halten muss, dann reichen diese Werkzeuge nicht mehr aus. In diesem Fall muss man auf die <em>Synchronisation</em> zurückgreifen.</p><p> </p><p> </p></div><footer class="wrapper post__footer"><p class="post__last-updated">This article was updated on Juni 20, 2022</p><ul class="post__tag"><li><a href="https://www.finecloud.ch/tags/java/">java</a></li><li><a href="https://www.finecloud.ch/tags/parallel/">parallel</a></li><li><a href="https://www.finecloud.ch/tags/softwareentwicklung/">software development</a></li></ul><div class="post__share"></div></footer></article></main><footer class="footer"><div class="footer__copyright"><p>Powered by Publii</p></div><button onclick="backToTopFunction()" id="backToTop" class="footer__bttop" aria-label="Back to top" title="Back to top"><svg><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#toparrow"/></svg></button></footer></div><script>window.publiiThemeMenuConfig = {
mobileMenuMode: 'sidebar',
animationSpeed: 300,
submenuWidth: 'auto',
doubleClickTime: 500,
mobileMenuExpandableSubmenus: true,
relatedContainerForOverlayMenuSelector: '.top',
};</script><script defer="defer" src="https://www.finecloud.ch/assets/js/scripts.min.js?v=6ca8b60e6534a3888de1205e82df8528"></script><script>var images = document.querySelectorAll('img[loading]');
for (var i = 0; i < images.length; i++) {
if (images[i].complete) {
images[i].classList.add('is-loaded');
} else {
images[i].addEventListener('load', function () {
this.classList.add('is-loaded');
}, false);
}
}</script><script defer="defer" src="https://www.finecloud.ch/media/plugins/syntaxHighlighter/prism.js"></script></body></html>