Java並行プログラミングには注意を払う必要がある

yieldメソッドは、現在のスレッドが実行状態(running状態)から実行可能状態(ready状態)に変更されることを意味します。CPUは多くの実行可能な状態から選択します。つまり、現在のスレッドは今もなお実行される可能性がありますが、他のスレッドが実行されて次回スレッドが実行されなくなるという意味ではありません。 。

マルチスレッドの場合、シェア変数の場合、データの一貫性を維持するために、synchronizedキーワードを使用できます。つまり、メソッドを追加できます。つまり、オブジェクトがロックされていますが、効率は高くありません。同期コードを使用できます。共有変数のみをロックしてセグメント化し、共有変数が数値の場合は、Atomicキーワードを使用して変数を変更します。同期して使用することはできません。このオブジェクトは、Java並行パッケージによって私に提供されたクラスで、加算および減算演算が含まれています

volatileキーワード、変数の値が変更されたときにCPUがキャッシュされますが、CPUは引き続きキャッシュ値からエラーを取得します。volatileキーワードは、値をメモリから取得する必要があることをCPUに通知します。可視性、原子性は実現できません。同時実行性の問題を解決
できません。同期化により、可視性と原子性の問題を実現できます。並行性の問題を解決できます

ThreadLocalの役割は、現在のスレッドにバインドすることです。このオブジェクトにはgetおよびsetメソッドがあり、その中にオブジェクトを置くことができ、複数のスレッドが共有変数をめぐって競合する状況はありません。

同期コンテナー:ベクトルハッシュテーブルCollections.synchronize()これらはいくつかの古いAPIであり、ソースコードは基本的に同期を使用して実装されるため、非常にかさばります。

**同時コンテナ:** Java 1.5で提供されるConcurrentHashMapセグメントロックAPI
ConcurrentHashMap map = new ConcurrentHashMap();
map .putIfAbsent(1,2)このメソッドは、キーが存在しない場合に挿入し、存在する場合は何も返しません。

CopyOnWriteArrayList / Setこれら2つの実装の基本原則は、最初に操作中にロックをロックし、次に共有リソースをコピーしてから、コピーされたリソースを使用することです。使用されるシナリオは、読み取りと書き込みを少なくすることです。運営

BlocakingQueueブロッキングキュー。2つの方法があります。1つは物を置く、1つは物をとる、キューは、水道管のように先入れ先出しで物を詰めるという特徴があります。上級者が最初に来る必要があります。

ロックされたフェンスセマフォ

ブロッキングとは、スレッドがすべて実行されたときに解放されることを意味します。CountDownLatchカウントダウンは

CountDownLatch  latch = new  CountDownLatch (2);   //表示有两个线程

latch.countDown()      //一般线程执行完之后调用这个方法,表示这个线程执行完了

latch.awit()          //这个方法必须是latch里面的线程都执行完了,才放行。

フェンスはダムに相当します。つまり、スレッドが特定の状態に達した後、このスレッドは引き続き動作します。

CyclicBarrier barrier = new CyclicBarrier (4)

barrier.await()   //只有当wait的线程等于4,才会继续往下走。不然都得等着。

セマフォの数が 5台のマシンなどのプロデューサとコンシューマの数と等しくない場合、8人がそれを使用する必要があり、最初は各人に1つ、次に誰かが解放して、別のワーカーが補います。

int t=8  //8个工人
Semaphore semaphore = new  Semaphore(5) //机器的数目

semaphore.acquire();   //意思是从5台机器中获取一个

semaphore.release();    //意思是机器释放,下一个工人就顶上。

スレッドプール

同時実行性が発生した場合は、スレッドプールを使用する必要があります。要求がないとスレッドを作成できないため、サーバーはそれを処理できません。

Executor executor = Executors.newFixedThreadPool(100);//意思是这个线程池有100个线程

executor.execute(线程)  //把线程扔进去,就可以了。他就执行线程的start方法。

Executor的实现类ExecutorService   这个类是Executor的实现类,里面有几个非常常用的方法。

スケジュールされたタスク

javaによって提供されるTimerクラスは、時間指定されたタスクを実装できます。
注:タイマーには2つの欠点があります。1つは、複数のタスクがある場合です。たとえば、元の2番目のタスクは1秒後に実行されますが、最初のタスクは2秒後に実行され、2番目のタスクは待機する必要があります。実行後にタスクを実行します。
もう1つは、最初のタスクがエラーを報告すると、タイマーのすべてのタスクがハングアップすることです。これは非常に深刻な結果です。

Timer timer=new Timer();
timer.schedule(线程,1000);//意思是1000毫秒之后执行线程


//如何解决这个问题呢?
//创建一个可调度的线程池
ScheduledExecutorService ExecutorService = Executors.newScheduleduledThreadPool(100);
EsxecutorService.schedule(线程,1000,TimerUnit.MILLISECONDS)//最后一个是指明1000的时间单位,这里是毫秒

デッドロック

ネストされたロックは、デッドロックの原因となることができ
、1つの避け、ネストされたロックネストされたシーケンス2をロックし、3本の紹介タイムアウトメカニズム:ソリューションを

ロックする

これはjava1.5によって提供される一種のロックであり、柔軟に制御できます。

Lock lock=new ReentrantLock();     //创建一个可重入锁

//主要有两个方法
lock.lock();      //加锁
locak.unlock();  //解锁
ReentrantReadWriteLock rwl= new  ReentrantReadWriteLock() ;  //创建一个既可以读又可以写的锁
rwl.writeLock().lock()   //创建一个写锁, 只能一个线程进来
rwl.writeLock().unlock() //释放写锁

rwl.readLock().lock()   //创建一个读锁, 可以有多个线程进来
rwl.readLock().unlock() //释放读锁

悲観的ロックと楽観的ロック-データベースレベル

悲観的ロック:運転中に一つだけのスレッドは、テーブルに読み取りまたは直接書き込みはロックされているかどうか、別のスレッドは、文実現するために来ることができなかった
更新の増加の後ろを

select * from user  for update

楽観的ロック:テーブルにバージョンフィールドを追加します。

分散ロック:redis zk

公開された281元の記事 ウォン称賛50 ビュー45万+

おすすめ

転載: blog.csdn.net/lzh657083979/article/details/79365217