TIL(2020-02-28)
ConcurrentModificationException ?
Observable
Effective Javaの例
ObservableSet
を作成し、要素を追加するときにSetに追加して、addNotifyElement
の購読者要素がSetに追加されたことを通知します.コールバック関数added
が生成されますが、ここではGramdaとして定義された関数は次のように表示されます.set.addObserver(new SetObserver<>() {
public void added(ObservableSet<E> set, E element){
print(element); // 귀찮아서 이렇게 적었습니다.
if(e == 23)
s.removeObserver(this);
}
});
참고 SetObservers
@FunctionalInterface
public interface SetObserver<E> {
//Call this function when ObservableSet added element
void added(ObservableSet<E> set, E element);
}
added
はコールバック関数です.しかし、現在、1つのスレッド自体がobservers
にロックされ、巡回中であり、突然外部から観察者にアクセスすることができる.すなわち、現在notifyElementAdded
はblock synchronized構造、public void notifyElementAdded(E element) {
synchronized (observers) {
for (SetObserver<E> observer : observers) {
observer.added(this, element);
}
}
}
この構造自体がadded
というコールバック関数の内部に同期できないからである.実際にDebuggingで1つずつそれを掴むと,まずaddに入り,次いで条件文でnotifyElementAdded
に入り,その後観察者をロックして観察者を巡回するときobserverのadd法を用いる.(まだ終わっていません)なので今簡単にメソッドスタックを描くと----------------------
| remove |
----------------------
| removeObservers |
----------------------
| added |
----------------------
| notifyElementAdded | => observers 에 lock 을 걸어주었음
----------------------
| add |
----------------------
はい、現在added
がremove
を呼び出し、notifyElementAdded
で動作する観察者の巡回途中で変化したため、ConcurrentModificationException
が発生して終了します.原因を詳しく説明する
我々の場合、for-loopはListであるため、for-loopは
Iterator
で実行され、IterクラスはAbstractList
(またはリストなど、Collection構造に依存)である最初に、modCount
変数は、自身の領域変数expectedModCount
に割り当てられ、add/removeなどのセットに関連する変更に関連するcountがmodCountに記録される.したがってnext()を行うと、既存の自己参照のCollectionがチェックされるのとは異なり、ConcurrentModificationException
が発生し、現在の場合はmodCount++が先に追加され、現在の状態はmodCount++(現在の状態1)であり、最後にremoveはmodCount+(2)が起動する.ただし、exptectModCountは既に1であるため、次の()を行うとConcurrentModificationException
が発生する.理解できなければ当日デバッグして見せます直接見たいなら[ArrayList.java](http://arraylist.java)
の956行967行Break Pointで確認できます簡単な知識
「拡張」for loopは、プロセッサを上書きすることによって使用されます.
ArrayList.javaのprivate class Itemは、私たちが初めて追加し、所望のModCount値に入った後、removeがコールバックされ、modCount++になり、エラーが発生します.うーん、Enhanced for loopも下とかなり似た場所(以下のコードを例にとると)に戻り、最初はmodCountに入りますが、このとき1が追加され、removeは2を生成し、最終的には最後の
if (modCount != expectedModCount)
でConcurrentModificationException
を生成します.public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
final Object[] es = elementData;
final int size = this.size;
for (int i = 0; modCount == expectedModCount && i < size; i++)
action.accept(elementAt(es, i));
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Concurrent Collection java
よい文章
Java ConcurrentHashMap
DB
データベースの概要
ドッキングステーションを外付けHDDに設定する
docker run -d -p 3307:3306 -v /Volumes/roach/docker/test:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1234 --name testingdb mysql:8.0.17 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
Sample Dataの挿入
MysqlはSample Dataを提供し、DockerでGitにファイルをダウンロードします.
Sample Data Link
ダウンロードした場合、test dbというディレクトリが作成されます.
mysql -uroot -p<password> -t employee.sql
このようにすると何か特別な更新がありますあちなみに最近は大音量デバッガも指定されているみたい?以前のバージョンは消えましたが、外付けハードディスク(HDD)にも大きな環境を構築したので、ボリュームパスを指定しました.とにかく、あなたがその命令を下すと、それは正常に追加されます~DB実習はこのようにしましょう!
非常に大きなサンプルデータもあり、これらのデータを手に入れてインデックスを勉強すれば、すぐに感覚を把握することができます.
テストアルゴリズム
コード四捨五入
Reference
この問題について(TIL(2020-02-28)), 我々は、より多くの情報をここで見つけました https://velog.io/@tmdgusya/TIL2020-02-28テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol