javaスレッド常用工具類の簡単な使用
10656 ワード
一Timerタイマー
Timer類は、アラームという周期的に変化するもののように、タイミングタスクを完成させるための機能です。
**1一番簡単なタイマー*
二秒後には時限爆弾が爆発します。
二秒後に一つの爆弾を爆発させてから、一秒ごとに一つずつ爆発させます。は、 。は、 である。
二ThreadLocalの使用
ThreadLocalはスレッドのローカル変数を作成するクラスです。通常、私たちは変数を作成するとき、この変数は任意のスレッドによってアクセスできます。
**簡単な例**
ThreadPoolは任務を処理するスレッド工場に相当します。工場内には多くのスレッド(労働者)があります。任務が来るたびに、スレッドは任務を実行します。任務が終わったらスレッド(労働者)は休みます。
医者の診察の簡単な例
ロックは、従来のスレッドの
1つの簡単なロックの例
二つのスレッドはそれぞれの文字列を出力し続け、各スレッドは文字列の整合性を保証します。
簡単なキャッシュ実現
Condationは、
行列をブロックする例
Semaphoreは現在のアクセスの個数を維持し、同期機構を提供し、同時にアクセスする個数を制御する。スレッド池が制御するのはスレッド数であり、信号量が制御するのは同時数であり、これは同じように見えるとはいえ、違いがあります。信号量の呼び出しは、数に達してもスレッドが存在します。ただ掛けられています。スレッドプールは、同時に実行するスレッドの数が固定されており、数を超えると待つしかない。 スレッドプールはスレッド多重である。信号量はスレッド同期 である。スレッドプールは複数のスレッド非同期実行タスクであり、信号量は制御タスクにおけるマルチスレッド同期領域である。 小例
10スレッド、3つのピット、毎回3つのスレッドに入ることができます。残りのスレッドは待ち時間があります。スレッドが離れると、待ちスレッドが入ることができます。
Timer類は、アラームという周期的に変化するもののように、タイミングタスクを完成させるための機能です。
**1一番簡単なタイマー*
二秒後には時限爆弾が爆発します。
@Test
public void test() {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println(" ");
}
},
2000);//
while (true) ;// ,
}
2周期的に実行するアラームを設定します。二秒後に一つの爆弾を爆発させてから、一秒ごとに一つずつ爆発させます。
@Test
public void test2() {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println(" ");
}
},
2000,
1000);// 1000ms 。
while (true) ;
}
注意:もし私たちがタスクを実行する場合、手動でこのタスクをキャンセルしたいなら、cancel()
方法を使ってキャンセルできます。Timer
クラスでの役割は、ジョブキュー内のすべてのタスクをキャンセルすることである(一つのTimer
は、複数のTimerTask
タスクを作成することができる)TimerTask
クラスでの役割は、自身のタスクをタスクキューからキャンセルする二ThreadLocalの使用
ThreadLocalはスレッドのローカル変数を作成するクラスです。通常、私たちは変数を作成するとき、この変数は任意のスレッドによってアクセスできます。
ThreadLocal
クラスを使って作成された変数は、変数を作成するスレッドにしかアクセスできません。他のスレッドはアクセスできません。**簡単な例**
public class _6_ThreadLocal {
@Test
public void test() {
ThreadLocal local = new ThreadLocal<>();
for (int i = 0; i < 5; ++i) {
final int index = i;
new Thread(new Runnable() {
@Override
public void run() {
synchronized (_6_ThreadLocal.class){
System.out.println(" :" + index);
local.set(" " + index + " ");
System.out.println(local.get());
}
}
}).start();
}
while (true);
}
}
三ThreadPoolスレッド池ThreadPoolは任務を処理するスレッド工場に相当します。工場内には多くのスレッド(労働者)があります。任務が来るたびに、スレッドは任務を実行します。任務が終わったらスレッド(労働者)は休みます。
ThreadPool
を使用するのは、プログラムのスループットを向上させるためであり、CPUの利用効率を向上させるためである。スレッド池は病院のようなもので、最初は一定数の医者(スレッド池の容量)を募集していましたが、患者が診察に来ると、医者は患者を診断しています。すべての医者が忙しいときは、病院は余分な医者を募集します。患者が減ると、病院はそれらの医師を解任します。医者の診察の簡単な例
public class _7_ThreadPool {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(3);//
// ExecutorService threadPool = Executors.newCachedThreadPool();//
// ExecutorService threadPool = Executors.newSingleThreadExecutor();//
for(int i = 0; i < 10; ++i) {
final int index = i;
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(" " +
Thread.currentThread().getName() + " " + index + " ");
}
});
}
}
}
四ロックロックは、従来のスレッドの
synchronized
よりもオブジェクトに向かっており、より便利である。lock
を使用すると、スレッド間相互反発の効果を達成するために複数のスレッドが実行されるコードブロックは、同じLock
オブジェクトを使用しなければならない。読み書きロック:読み取りロックと書き込みロックに分けられており、複数の読み取りロックの間では互いに反発せず、読み取りロックと書き込みロックの間でも互いに反発し、書き込みロックと書き込みロックの間でも互いに反発します。1つの簡単なロックの例
二つのスレッドはそれぞれの文字列を出力し続け、各スレッドは文字列の整合性を保証します。
public class _8_Lock {
private static Lock lock = new ReentrantLock();//
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Ouput().output("HHHHHHHHHH");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Ouput().output("aaaaaaaaa");
}
}
}).start();
}
static class Ouput{
public void output(String name) {
lock.lock();//
try {
for(int i = 0; i < name.length(); ++i) {
System.out.print(name.charAt(i));
}
System.out.println();
}finally {
lock.unlock();//
}
}
}
}
2読み書きロックの例簡単なキャッシュ実現
public class _9_CacheDemo {
private Map data = new HashMap<>();
public static void main(String[] args) {
System.out.println(new _9_CacheDemo().getData("haha").toString());
}
private ReadWriteLock rwl = new ReentrantReadWriteLock();
public Object getData(String key) {
Object value = null;
rwl.readLock().lock();
try {
value = data.get(key);
if (value == null) {
rwl.readLock().unlock(); // , readLock , writeLock (1)
rwl.writeLock().lock();
try {
if (value == null) {// if value, (1)
value = "hehe";
}
}finally {
rwl.writeLock().unlock();
}
}
rwl.readLock().lock();// readLock finally unLock
}finally {
rwl.readLock().unlock();
}
return value;
}
}
五コンデントCondationは、
Object
のwait()、notify()、notifyAll()
方法を異なるオブジェクトに分解して、より良いものとLock
を組み合わせて使用するようにします。Lock
はsynchronized
の代わりに、Condition
もObejct
によって監視される方法に取って代わっている。Condition
を使用する利点は、3つのスレッドA、B、Cなどの他のスレッドを選択的に起動することができ、現在はAスレッドを実行し、最後にCスレッドを実行する必要があり、Condition
を使用すれば良く解決できることである。行列をブロックする例
public class _10_Condition {
final Lock lock = new ReentrantLock();
final Condition fullCondition = lock.newCondition();
final Condition emptyCondition = lock.newCondition();
final Object[] datas = new Object[10];
int putIndex, takeIndex, count;
public static void main(String[] args) {
_10_Condition condition = new _10_Condition();
//
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 50; ++i) {
try {
Thread.sleep(new Random().nextInt(2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
condition.put(i);
}
}
}).start();
//
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 50; ++i) {
try {
Thread.sleep(new Random().nextInt(2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
condition.get();
}
}
}).start();
}
public void put(Object data) {
lock.lock();
try {
while (count == datas.length) { // , put
System.out.println("the arrays is full");
fullCondition.await();
}
datas[putIndex] = data;
System.out.println(Thread.currentThread().getName() + " put the data-------> " + data);
++count;
if (++putIndex == datas.length) {
putIndex = 0;
}
emptyCondition.signal(); // , take
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public Object get() {
lock.lock();
try {
while (count == 0) { // , take
System.out.println("the arrays is empty");
emptyCondition.await();
}
Object obj = datas[takeIndex];
System.out.println(Thread.currentThread().getName() + " get the data " + obj);
--count;
if (++takeIndex == datas.length) {
takeIndex = 0;
}
fullCondition.signal(); // , put
return obj;
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return null;
}
}
6 SemaphoreSemaphoreは現在のアクセスの個数を維持し、同期機構を提供し、同時にアクセスする個数を制御する。
Semaphore
とThreadPool
は機能が似ていますが、違いがあります。10スレッド、3つのピット、毎回3つのスレッドに入ることができます。残りのスレッドは待ち時間があります。スレッドが離れると、待ちスレッドが入ることができます。
public class _10_Semaphore {
public static void main(String[] args) {
Semaphore sp = new Semaphore(3);
for(int i = 0 ; i < 10; ++i) {
new Thread(new Runnable() {
@Override
public void run() {
try {
sp.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" , " + (3 - sp.availablePermits())+" ");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "+", " + (3 - sp.availablePermits())+" ");
sp.release();
}
}).start();
}
}
}
ソースアドレス