1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
---
title: Atomics
slug: Web/JavaScript/Reference/Global_Objects/Atomics
tags:
- JavaScript
- Namespace
- Shared Memory
- Specifications
- 仕様
- 共有メモリ
- 名前空間
translation_of: Web/JavaScript/Reference/Global_Objects/Atomics
---
<div>{{JSRef}}</div>
<p><strong><code>Atomics</code></strong> オブジェクトは、静的なメソッドとして不可分操作を提供します。これらは {{jsxref("SharedArrayBuffer")}} および {{jsxref("ArrayBuffer")}} オブジェクトで使用されます。</p>
<h2 id="Description" name="Description">解説</h2>
<p>不可分操作は、 <code>Atomics</code> モジュール上に装備されています。他のグローバルオブジェクトと異なり、 <code>Atomics</code> はコンストラクターではありません。 <a href="/ja/docs/Web/JavaScript/Reference/Operators/new"><code>new</code> 演算子</a> を付けて使用したり、 <code>Atomics</code> オブジェクトを関数として呼び出したりすることはできません。 <code>Atomics</code> のすべてのプロパティとメソッドは静的です (例えば、{{jsxref("Math")}} オブジェクトの場合と同様です)。</p>
<h3 id="Atomic_operations" name="Atomic_operations">不可分操作</h3>
<p>メモリが共有されている場合、複数のスレッドがメモリー内の同じデータを読み書きできます。不可分操作では、予測される値の書き込みと読み込みを保証するため、次の演算が開始される前に現在の演算が完了し、その演算が割り込まれないようにします。</p>
<h3 id="Wait_and_notify" name="Wait_and_notify">wait と notify</h3>
<p><code>wait()</code> メソッドと <code>notify()</code> メソッドは、 Linux の futex ("fast user-space mutex") を原型としており、特定の条件が true になるまで待つ手段を提供します。一般的にはブロッキング構造として使用されます。</p>
<h2 id="Static_methods" name="Static_methods">静的メソッド</h2>
<dl>
<dt>{{jsxref("Atomics.add()")}}</dt>
<dd>配列の指定した位置にある既存の値に指定した値を追加します。その位置にあった古い値を返します。</dd>
<dt>{{jsxref("Atomics.and()")}}</dt>
<dd>配列の指定した位置の値と指定した値でビット単位の論理積 (AND) を計算します。その位置にあった古い値を返します。</dd>
<dt>{{jsxref("Atomics.compareExchange()")}}</dt>
<dd>値が等しい場合、配列の指定した位置に値を格納します。古い値を返します。</dd>
<dt>{{jsxref("Atomics.exchange()")}}</dt>
<dd>配列の指定した位置に値を格納します。古い値を返します。</dd>
<dt>{{jsxref("Atomics.isLockFree()", "Atomics.isLockFree(size)")}}</dt>
<dd>ロック機構と不可分操作のどちらを使用するかを決定するための最適化プリミティブです。指定した要素サイズの配列上の不可分操作が (ロックではなく) ハードウェアによる不可分操作を使用するよう実装されている場合、 <code>true</code> を返します。上級者だけが使用してください。</dd>
<dt>{{jsxref("Atomics.load()")}}</dt>
<dd>配列の指定した位置の値を返します。</dd>
<dt>{{jsxref("Atomics.notify()")}}</dt>
<dd>配列の指定した位置で待機中のエージェントに通知します。通知を受けたエージェントの数を返します。</dd>
<dt>{{jsxref("Atomics.or()")}}</dt>
<dd>配列の指定した位置の値と指定した値でビット単位の論理和 (OR) を計算します。その位置にあった古い値を返します。</dd>
<dt>{{jsxref("Atomics.store()")}}</dt>
<dd>配列の指定した位置に指定した値を格納します。その値を返します。</dd>
<dt>{{jsxref("Atomics.sub()")}}</dt>
<dd>配列の指定した位置の値から指定した値を減算します。その位置にあった古い値を返します。</dd>
<dt>{{jsxref("Atomics.wait()")}}</dt>
<dd>配列の指定位置に指定した値が含まれているか検証し、休止して待機するかタイムアウトします。 "<code>ok</code>", "<code>not-equal</code>", "<code>timed-out</code>" のいずれかの文字列を返します。呼び出したエージェントで待機が許可されていない場合は、 Error 例外を投げます (ほとんどのブラウザーは、ブラウザーのメインスレッドで <code>wait()</code> を許可していません)。</dd>
<dt>{{jsxref("Atomics.xor()")}}</dt>
<dd>配列の指定した位置の値と指定した値でビット単位の排他的論理和 (XOR) を計算します。その位置にあった古い値を返します。</dd>
</dl>
<h2 id="Examples" name="Examples">例</h2>
<h3 id="Using_Atomics" name="Using_Atomics">Atomics の使用</h3>
<pre class="brush: js notranslate">const sab = new SharedArrayBuffer(1024);
const ta = new Uint8Array(sab);
ta[0] = 5;
Atomics.add(ta, 0, 12);
Atomics.load(ta, 0); // 12
Atomics.and(ta, 0, 1);
Atomics.load(ta, 0); // 1
Atomics.compareExchange(ta, 0, 5, 12);
Atomics.load(ta, 0); // 12
Atomics.exchange(ta, 0, 12);
Atomics.load(ta, 0); // 12
Atomics.isLockFree(1); // true
Atomics.isLockFree(2); // true
Atomics.isLockFree(3); // false
Atomics.isLockFree(4); // true
Atomics.or(ta, 0, 1);
Atomics.load(ta, 0); // 5
Atomics.store(ta, 0, 12); // 12
Atomics.sub(ta, 0, 2);
Atomics.load(ta, 0); // 3
Atomics.xor(ta, 0, 1);
Atomics.load(ta, 0); // 4
</pre>
<h3 id="Waiting_and_notifiying" name="Waiting_and_notifiying">待機と通知</h3>
<p>共有された <code>Int32Array</code> があるとします。</p>
<pre class="brush: js notranslate">const sab = new SharedArrayBuffer(1024);
const int32 = new Int32Array(sab);
</pre>
<p>読み取りスレッドはスリープ状態で、 0 の位置が 0 である間は待機しています。これが true である限り、スレッドは進みません。しかし、書き込みスレッドが新しい値を格納すると、書き込みスレッドから通知され、新しい値 (123) を返します。</p>
<pre class="brush: js notranslate">Atomics.wait(int32, 0, 0);
console.log(int32[0]); // 123</pre>
<p>書き込みスレッドが新しい値を格納し、待機しているスレッドに書き込みが発生したことを通知します。</p>
<pre class="brush: js notranslate">console.log(int32[0]); // 0;
Atomics.store(int32, 0, 123);
Atomics.notify(int32, 0, 1);</pre>
<h2 id="Specifications" name="Specifications">仕様書</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">仕様書</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('ESDraft', '#sec-atomics-object', 'Atomics')}}</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2>
<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div>
<p>{{Compat("javascript.builtins.Atomics")}}</p>
<h2 id="See_also" name="See_also">関連情報</h2>
<ul>
<li>{{jsxref("ArrayBuffer")}}</li>
<li><a href="/ja/docs/Web/JavaScript/Typed_arrays">JavaScript 型付き配列</a></li>
<li><a href="/ja/docs/Web/API/Web_Workers_API">ウェブワーカー</a></li>
<li><a href="https://github.com/lars-t-hansen/parlib-simple">parlib-simple</a> – 同期と分配の抽象化を行うシンプルなライブラリ。</li>
<li><a href="https://github.com/tc39/ecmascript_sharedmem/blob/master/TUTORIAL.md">Shared Memory – 簡潔なチュートリアル</a></li>
<li><a href="https://dev.mozilla.jp/2016/05/a-taste-of-javascripts-new-parallel-primitives/">JavaScript の並列処理機能を味見してみる</a></li>
</ul>
|