JAvaマルチスレッドまとめ学習-Queue、コンテナ、単例モード
8762 ワード
1、単例モードはマルチスレッドをサポートする
単例モード:よく使われる2つのモード:餓漢モード怠け者モードですが、この2つのモードはマルチスレッドアプリケーションシーンでは安全ではありません.
マルチスレッドに適用し、スレッドの安全を保障するために、double check instance、static inner classの2つを使用します.
(1)static inner class
(2)double check instance
2、同期クラスコンテナ、同時クラスコンテナ同期クラス:vector hashTable(下部にsynchronid修飾を付け、同期を実現したが、同時効率に影響する)
同時クラス:Queue、concurrentMap、LinkedBlockingQueue、CopyOnWrite
(1)ConcurrentHashMap:セグメントsegmentで複数のセグメントを分割し、各セグメントはhashTableに相当し、対応するロックがあり、最大16個のセグメントをサポートする
スレッドごとに異なるセグメントにアクセス
作用:ロック粒度を減らし、ロック競合を減らす
最下位でvolatileキーワードを大量に使用し、共有変数を実現
(2)Copy-ON-Write(COW)CopyOnWriteArrayListとCopyOnWriteArraySet
書き込み時にコピーしたコンテナ、読み書き分離を実現
スレッドがコンテナを操作(削除)すると、コンテナを直接操作するのではなく、同じコンテナをコピーして操作し、操作が完了すると、元のコンテナのポインタをコピーしたコンテナに指します.
他のスレッドが読み取りを行う場合、元のコンテナを直接読み取り、読み書き相分離を実現する
適用シーン:読み書きが少ない場合
3、同時queue ConcurentLinkedQueue:非ブロック、性能が高く、高同時
BlockingQueue:ブロックされた
ConcurentLinkedQueue:
先頭が先頭で、先頭が先頭で、末尾が最も近いのでnull値は許されません
add()offer()は要素を入れて、ConcurentLinkedQueueの中で区別がありません
Poll()peek()ヘッダ要素、前者は要素を削除し、後者は削除しない
BlockingQueue:,ブロック
1、ArrayBlockingQueue、配列、境界行列に基づいて、ブロックする
2、LinkedBlockingQueue無境界キュー、ブロック
3、synchronousQueue:バッファのないキューでは要素を追加できません
4、priorityBlockingQueue:優先順位に基づくブロックキューで、キューに入ったオブジェクトはcomparableインタフェースが先進的な先出しに従わないことを実現しなければならない
5、DelayQueue:要素はdelayedインタフェースを実現しなければならない.要素は遅延時間に達しなければ、取り出されない
(1)ConcurentLinkedQueue
(2)BlockingQueue(ArrayBlockingQueue、linkedBlockingQueue、SynchronousQueue)
(3)PriorityBlockingQueue.シミュレーションシーン:タスクがある場合、タスクIDに従って優先度に従って解放されます.
実行結果:
コンテナ:[1,タスク1,4,タスク2,3,タスク3]1コンテナ:[3,タスク3,4,タスク2]3 4
(4)DelayQueue,シミュレーションシーン,ネットカフェでチェックイン,時間までダウン
実行結果:
ネットユーザー:張三が搭乗を開始し、搭乗時間は1秒
ネットユーザー:李四は飛行機に乗ることを始めて、飛行機に乗る時間の10秒
ネットユーザー:王五は飛行機に乗ることを始めて、飛行機に乗る時間の5秒
网民:张三下机..
ネットユーザー:王五下机..
ネットユーザー:李四下机..
単例モード:よく使われる2つのモード:餓漢モード怠け者モードですが、この2つのモードはマルチスレッドアプリケーションシーンでは安全ではありません.
マルチスレッドに適用し、スレッドの安全を保障するために、double check instance、static inner classの2つを使用します.
(1)static inner class
package thread;
/**
* ,
* static inner class
*
*/
public class SingleInner {
private static class Singleton{
private static Singleton single = new Singleton();
}
public static Singleton getInstance(){
return Singleton.single;
}
}
(2)double check instance
public class Singleton{
// ,
private static Singleton instance = null;
// ,
private Singleton(){
}
private static synchronized void syncInit(){
if(instance == null){
instance = new Singleton();
}
}
public static Singleton getInstance(){
if(instance == null){
syncInit();
}
return instance;
}
}
2、同期クラスコンテナ、同時クラスコンテナ同期クラス:vector hashTable(下部にsynchronid修飾を付け、同期を実現したが、同時効率に影響する)
同時クラス:Queue、concurrentMap、LinkedBlockingQueue、CopyOnWrite
(1)ConcurrentHashMap:セグメントsegmentで複数のセグメントを分割し、各セグメントはhashTableに相当し、対応するロックがあり、最大16個のセグメントをサポートする
スレッドごとに異なるセグメントにアクセス
作用:ロック粒度を減らし、ロック競合を減らす
最下位でvolatileキーワードを大量に使用し、共有変数を実現
(2)Copy-ON-Write(COW)CopyOnWriteArrayListとCopyOnWriteArraySet
書き込み時にコピーしたコンテナ、読み書き分離を実現
スレッドがコンテナを操作(削除)すると、コンテナを直接操作するのではなく、同じコンテナをコピーして操作し、操作が完了すると、元のコンテナのポインタをコピーしたコンテナに指します.
他のスレッドが読み取りを行う場合、元のコンテナを直接読み取り、読み書き相分離を実現する
適用シーン:読み書きが少ない場合
3、同時queue ConcurentLinkedQueue:非ブロック、性能が高く、高同時
BlockingQueue:ブロックされた
ConcurentLinkedQueue:
先頭が先頭で、先頭が先頭で、末尾が最も近いのでnull値は許されません
add()offer()は要素を入れて、ConcurentLinkedQueueの中で区別がありません
Poll()peek()ヘッダ要素、前者は要素を削除し、後者は削除しない
BlockingQueue:,ブロック
1、ArrayBlockingQueue、配列、境界行列に基づいて、ブロックする
2、LinkedBlockingQueue無境界キュー、ブロック
3、synchronousQueue:バッファのないキューでは要素を追加できません
4、priorityBlockingQueue:優先順位に基づくブロックキューで、キューに入ったオブジェクトはcomparableインタフェースが先進的な先出しに従わないことを実現しなければならない
5、DelayQueue:要素はdelayedインタフェースを実現しなければならない.要素は遅延時間に達しなければ、取り出されない
(1)ConcurentLinkedQueue
package queue;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* ConcurrentLinkedQueue , ,
* , , , null
* add() offer() , ConcurentLinkedQueue
* poll() peek() , ,
*/
public class UseConcurrentQueue {
public static void main(String[] args) {
ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
q.add("a");
q.add("b");
q.add("c");
q.add("d");
q.offer("e");
q.offer("f");
System.out.println(q.size());
System.out.println(q.poll());
System.out.println(q.size());
System.out.println(q.peek());
System.out.println(q.size());
}
}
(2)BlockingQueue(ArrayBlockingQueue、linkedBlockingQueue、SynchronousQueue)
package queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
/**
* BlockingQueue:
* ArrayBlockingQueue: ,
* linkedBlockingQueue: , , , , ,
* SynchronousQueue: ,take() , take , add, add ,
*
*/
public class UseBlockingQueue {
public static void main(String[] args) throws Exception{
//ArrayBlockingQueue
ArrayBlockingQueue aq = new ArrayBlockingQueue(5);
aq.add("a");
aq.add("b");
aq.put("c");
aq.put("d");
aq.offer("e");
aq.offer("f");
System.out.println("ArrayBlockingQueue:"+aq);
//linkedBlockingQueue
LinkedBlockingQueue lq = new LinkedBlockingQueue<>();
lq.add("a");
lq.add("b");
lq.put("c");
lq.put("d");
lq.offer("e");
lq.offer("f");
System.out.println("LinkedBlockingQueue :"+lq);
LinkedBlockingQueue lq2 = new LinkedBlockingQueue<>(4);
lq2.add("a");
lq2.add("b");
lq2.put("c");
lq2.put("d");
lq2.offer("e");
lq2.offer("f");
System.out.println("LinkedBlockingQueue :"+lq2);
//synchronousQueue
final SynchronousQueue sq = new SynchronousQueue<>();
//sq.add("a"); // java.lang.IllegalStateException: Queue full
Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
try {
sq.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
sq.add("a");
System.out.println("SynchronousQueue:"+sq);
}
});
t2.start();
}
}
(3)PriorityBlockingQueue.シミュレーションシーン:タスクがある場合、タスクIDに従って優先度に従って解放されます.
package queue;
import java.util.concurrent.PriorityBlockingQueue;
import queue.priority.Task;
/**
* PriorityBlockingQueue:
* comparable ,
* take , ( )
*
*/
public class UsePriorityBlockingQueue {
public static void main(String[] args) throws Exception{
PriorityBlockingQueue pq = new PriorityBlockingQueue();
Task t1 = new Task();
t1.setId(1);
t1.setName(" 1");
Task t2 = new Task();
t2.setId(4);
t2.setName(" 2");
Task t3 = new Task();
t3.setId(3);
t3.setName(" 3");
pq.add(t1);
pq.add(t2);
pq.add(t3);
System.out.println(" :"+pq.toString());
System.out.println(pq.take().getId());
System.out.println(" :"+pq.toString());
System.out.println(pq.take().getId());
System.out.println(pq.take().getId());
}
}
package queue.priority;
public class Task implements Comparable{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Task o) {
return this.id > o.id ? 1 : (this.id > o.id ? -1 : 0);
}
public String toString(){
return this.id + "," + this.name;
}
}
実行結果:
コンテナ:[1,タスク1,4,タスク2,3,タスク3]1コンテナ:[3,タスク3,4,タスク2]3 4
(4)DelayQueue,シミュレーションシーン,ネットカフェでチェックイン,時間までダウン
package queue;
import java.util.concurrent.DelayQueue;
import queue.delay.Wangmin;
/**
* DelayQueue:
* delayed
* ,
*/
public class UseDelayQueue implements Runnable{
DelayQueue dq = new DelayQueue();
public void shangji(int id, String name, int money){
Wangmin wm = new Wangmin(id,name,1000*money+System.currentTimeMillis());
dq.add(wm);
System.out.println(" :"+name+" , "+money+" ");
}
public void xiaji(Wangmin wm){
System.out.println(" :"+wm.getName()+" 。。。");
}
@Override
public void run() {
while(true){
try {
Wangmin wm = dq.take();
xiaji(wm);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
UseDelayQueue udq = new UseDelayQueue();
Thread t = new Thread(udq);
t.start();
udq.shangji(1," ",1);
udq.shangji(2," ",10);
udq.shangji(3," ",5);
}
}
package queue.delay;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
*
* Delayed
* getDelay、compareTo
*/
public class Wangmin implements Delayed{
private int id;
private String name;
private long endtime;
private TimeUnit timeUnit = TimeUnit.SECONDS;// ,
//
public Wangmin(int id, String name, long endtime){
this.id=id;
this.name = name;
this.endtime = endtime;
}
@Override
public int compareTo(Delayed delay) {
Wangmin w = (Wangmin)delay;
return this.getDelay(this.timeUnit) > w.getDelay(this.timeUnit) ? 1 : 0;
}
@Override
public long getDelay(TimeUnit arg0) {
return endtime - System.currentTimeMillis();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getEndtime() {
return endtime;
}
public void setEndtime(long endtime) {
this.endtime = endtime;
}
}
実行結果:
ネットユーザー:張三が搭乗を開始し、搭乗時間は1秒
ネットユーザー:李四は飛行機に乗ることを始めて、飛行機に乗る時間の10秒
ネットユーザー:王五は飛行機に乗ることを始めて、飛行機に乗る時間の5秒
网民:张三下机..
ネットユーザー:王五下机..
ネットユーザー:李四下机..