ディレクトリ
この1人の十分な友人は、マルチスレッドの基礎を学びます!(A):HTTPS://blog.csdn.net/weixin_43827227/article/details/96606212
パートIV:スレッド間通信
コンセプト:同じプロセスのリソースで複数のスレッドが、タスクが異なっています。(銀行では、それはお金を節約するために、一部の人々がお金を引き出すでした)
待機ウェイクアップ機構
この方法は、以下のものを含みます:
1、)(待つ:冷凍状態でスレッドを作る、待機スレッドは、スレッドプールに保存されます。
2は、通知():スレッドプールのスレッド(任意)を覚まします。
3、のnotifyAll():スレッドプール内のすべてのスレッドを覚まします。
なぜ、これらの方法は、同期に定義する必要がありますされていますか?
この方法は、スレッドの状態を操作するための方法だからです。私たちは、スレッドがロックされている操作の終わりに明確でなければなりません。
スレッド待ちの操作方法は、のnotifyAllがObjectクラスで定義された通知はなぜ?
これらのメソッドは、メソッドのモニターされているため。実際にモニターロック:同期(すなわち、オブジェクトロック)。
ロックは、任意のオブジェクトの任意のオブジェクトは、オブジェクト・クラスと呼ばれる特定の方法で定義されてもよいです。
プロセス:
例:
//用等待唤醒注意点: 1, 同步函数 2,wait和notify成对
//wait,notify,notifyAll这些方法都必须定义在同步中
public synchronized void set(String name,String sex)
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
}
例:マルチプロデューサー多くの消費者問題
一度だけ決定マーク場合、スレッドの実行を実行する必要がありますが発生します。データエラーが発生しました。
フラグを判断しながら、糸の後に解決を実行したい場合は、右実行されます!
通知:パーティーのパーティーのきっかけは、意味がない場合にのみ、1つのスレッド(複数のセット)を覚まします。決定マーク+がデッドロックになります通知ながら(判断を目覚めながら行われ、すべてのスレッドは、デッドロックを待って、再び待ちます)。
他のスレッドを起動しますパーティのスレッドの問題を解決するためのnotifyAll。
(ただし、この方法は判断をしながら、彼らはこれが最適化された.JDK1.5の効率を低下させ、党を覚ます、反対側を覚ますだけではなく)
現在、結論:農産物より多くの消費、裁判官としばらく目を覚ましとのnotifyAll
短所:、反対側を覚ます判断をしながら、パーティーを覚ます、効率が低下するだけでなく、
class Resource2 {
private String nameString="烤鸭";
private int count =1;
private boolean flag =false;
// Lock lock=new ReentrantLock();
// Condition condition =lock.newCondition();
public synchronized void set(String name) {
while(flag)
//if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
//while判断标记,解决了线程获取执行权后,是否要运行!
//notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。
//结论:多生产多消费时,用while 和 notifyAll进行判断与唤醒
//弊端:既唤醒对方,又唤醒本方,在进行while判断,降低了效率
try {
this.wait();
} catch ( InterruptedException e) {
}
count=count+1;
System.out.println(Thread.currentThread().getName()+"。。。。。生产者。。。。。"+this.nameString+count);
flag=true;
notifyAll(); //notifyAll解决了本方线程一定会唤醒对方线程的问题。
}
public synchronized void out() {//与上面的格式进行对比
// lock.lock();
try {
while(!flag)
try {
this.wait();
} catch ( InterruptedException e) {
}
System.out.println(Thread.currentThread().getName()+"。。。。。。。。消费者。。。。。。"+this.nameString+count);
flag=false;
notifyAll();
} finally {
// lock.unlock();
}
}
}
class Producer2 implements Runnable{
private Resource2 r; //传递参数 创建资源对象,然后传递给set out
Producer2(Resource2 r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
class Consumer implements Runnable
{
private Resource2 r; //传递参数 创建资源对象,然后传递给set out
Consumer(Resource2 r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
public class ProducerConsumerDemo {
public static void main(String[] args) {
Resource2 resource2 =new Resource2();
Producer2 producer2=new Producer2(resource2);
Consumer consumer=new Consumer(resource2);
Thread t1=new Thread(producer2);
Thread t2=new Thread(producer2);
Thread t3=new Thread(consumer);
Thread t4=new Thread(consumer);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
-------------------------------------------------- -------------------------------------------------- -----------------------------------------
最適化:新機能のロック、条件
ロックの交換は、同期
これらの条件モニタへの代替方法(待機中のオブジェクトは、通知、およびのnotifyAll)
-------------------------------------------------- -------------------------------------------------- -----------------------------------------
差分:同期コードと同期機能ブロックのみがパッケージされる前に、ロックが付属して(ロック操作:取得し、放出は、可視暗黙的ではありません)。
(ロックを提供する)とアンロック()メソッド即ち取得し、放出ロック両者の:今ロックオブジェクトがロックにカプセル化されます
そしてロックの任意の組み合わせであってもよいです
-------------------------------------------------- ----------------------------
-------------------------------------------------- -----------------------------
Lock lock=new ReentrantLock();
Condition condition =lock.newCondition();
public synchronized void out() {
while(!flag)
try {
//this.wait();
condition.await ();
} catch ( InterruptedException e) {
}
this.nameString =nameString+count;
System.out.println(Thread.currentThread().getName()+"。消费者。。。。。。"+this.nameString);
flag=false;
//notifyAll();
condition.signalAll();
}
//这样子功能没有变化,与之前一致。
//------------------------------------------------
//下面是优化后
//若通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。(则可体现优化所在:一个锁可以显加上多组监视器)
Condition producer_con = lock.newCondition();//监听生产者
Condition consumer_con = lock.newCondition();//监听消费者
public void out() {//与上面的格式进行对比
lock.lock();
try {
while(!flag)
try {
consumer_con.await(); //指定沉睡一个消费者的线程
} catch ( InterruptedException e) {
}
System.out.println(Thread.currentThread().getName()+"。消费者。。。。。。"+this.nameString+count);
flag=false;
producer_con.signal();//指定唤醒一个生产者的线程
} finally {
lock.unlock();
}
}
待ってスリープの違いは?
1は、指定した時間がよい待つか指定することはできません。
スリープ時間を指定する必要があります。
2、同期、CPUの実行権とは異なるロックを扱うとき。
待つ:ロックを解除する権利の実装のリリースを。
睡眠:執行力の解除、ロックを解除していません。
停止スレッド
runメソッドの終わり。
制御タスクのスレッドが終了する方法は?
ミッションは、限り、あなたはタスクを終了サイクルを制御することができますよう、ループ構造を持つことになります。
制御周期は通常、タグの定義によって達成されます。
スレッドは凍結状態にある場合でも、ラベルを読み取ることができません。どのようにそれを終了するには?
あなたはこの方法では、過去の状態に凍結状態から実行中のスレッドを再開することを余儀なくされます()割り込みを使用することができますので、CPUの資格を持つ実行スレッド。
しかし、強制アクションは、ハンドルに覚えて、InterruptedExceptionあるが発生します
デーモンスレッド
バックグラウンドスレッドとして理解することができ、フォアグラウンドスレッドの終了は、スレッド・デーモン(バックグラウンドスレッド)が自動的に終了しました。
スレッドの優先順位
t2.setPriority(Thread.MAX_PRIORITY)。
デフォルトの優先順位は、スレッド5作成することです(1〜10、より有利な大きな優先順位を、だけでなく、CPUのリソースを押収する必要があります)