JAVAマルチスレッドマルチプロセスVS

著作権:任意、https://blog.csdn.net/qq_32662595/article/details/84850304を播種!

A.意味

  1. プロセス
    メモリにプログラムを実行するには、それがプロセスになります。プロセスは、プログラムを実行するプロセスです。プロセスは、リソースの割り当てとスケジューリングシステム独立したユニットを操作しています。
  2. スレッドの
    スレッド、プロセス、単位工程の実際の動作に含まれる動作スケジュール、可能なオペレーティングシステムの最小単位です。スレッドはまた、軽量プロセスと呼ばれています。スレッドは独立した、同時ストリームの過程にあります。

II。特徴
1.プロセスを
実体の独立した存在の独立1.、各プロセスは、メモリ空間の独自の個別のプライベートの部分を持っています。
2.動的プログラムは、命令の単なる静的な集合であり、命令処理は、システムコレクション内の継続的な活動です。
3.プロセスの同時実行複数は、単一のプロセッサ上で同時に実行することができます。
説明:
並行性と並列
同じ時点で同時は、唯一の命令が実行されることをいうが、命令は、迅速に回転処理の複数であるので、マクロ上で実行する複数のプロセスを有するの効果。
これは、並行して同じ時点に同時に複数のプロセッサ上で実行される複数の命令を指します。

III。差

 1.  线程是进程的组成部分,一个进程可以有很多线程,每条线程并行执行不同的任务。
	 2. 不同的进程使用不同的内存空间,而线程与父进程的其他线程共享父进程的所拥有的全部资源。这样编程方便了,但是要更加小心。
	 3. 别把内存空间和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。线程拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不拥有系统资源。
	 4. 线程的调度和管理由进程本身负责完成。操作系统对进程进行调度,管理和资源分配。
4. 优势
	1. 多线程
		1. 进程之间不能共享内存,但线程之间共享内存。
		2. 系统创建进程时需要为该进程重新分配系统资源,但创建线程则代价小很多,效率高。
		3. 资源利用率更好
		4. 程序设计更简单
		5. 程序响应更快 

第三に、Javaのスレッドでメソッドを作成します

  1. Threadクラス継承Threadクラスは、作成し
    たクラスのrun()メソッドを書き換え、Threadクラス定義のサブクラスを。このメソッドは、実行スレッドです。
    スレッドのサブクラスのインスタンスを作成します。そのスレッドのオブジェクト。
    スレッドを開始するスレッドオブジェクトのstart()メソッドを呼び出します

  2. クラスを達成するためにスレッドを作成するには、Runnableインタフェース
    インタフェースの、Runnableインタフェース、オーバーライドrun()メソッドを実装-definedクラスを。このメソッドは、実行スレッドです。
    Runnableを実装クラスのインスタンスを作成します。スレッドThreadオブジェクトを作成するために、ターゲットの一例として、それを使用しています。Threadオブジェクトは、実際のスレッドオブジェクトです。
    スレッドを開始するスレッドオブジェクト(Threadオブジェクト)start()メソッドを呼び出します。

  3. 使用呼び出し可能と未来は、スレッドを作成します

    //Callable
     public class CallableAndFuture {
         public static void main(String[] args) {
             Callable<Integer> callable = new Callable<Integer>() {
                 public Integer call() throws Exception {
                     return new Random().nextInt(100);
                 }
             };
             FutureTask<Integer> future = new FutureTask<Integer>(callable);
             new Thread(future).start();
             try {
                 Thread.sleep(5000);// 可能做一些事情
                 System.out.println(future.get());
             } catch (InterruptedException e) {
                 e.printStackTrace();
             } catch (ExecutionException e) {
                 e.printStackTrace();
             }
         }
     }
    
     // **Future**
     public class CallableAndFuture {
         public static void main(String[] args) {
             ExecutorService threadPool = Executors.newSingleThreadExecutor();
             Future<Integer> future = threadPool.submit(new Callable<Integer>() {
                 public Integer call() throws Exception {
                     return new Random().nextInt(100);
                 }
             });
             try {
                 Thread.sleep(5000);// 可能做一些事情
                 System.out.println(future.get());
             } catch (InterruptedException e) {
                 e.printStackTrace();
             } catch (ExecutionException e) {
                 e.printStackTrace();
             }
         }
     }
    

第四に、対照的にRunnableをスレッドまたはThreadJava 2つのメソッドを作成?
Javaのマルチスレッドでは、Runnableを継承Threadクラスは、以下の利点と欠点を持っている実装と比較して、一般的に、複数のスレッドを作成するには、Runnableインタフェースを実現することをお勧めします:
のみインタフェースを実装Runnableを、Threadクラスを実装し、あなたが他のクラスから継承することができ、相続スレッド事の種類は、他の親を継承することはできません。
、Runnableインタフェースを達成するための状況は、複数のスレッドが同じターゲット・オブジェクトなので、同じリソースを扱う複数のスレッド地区で同じプログラムコードを共有することができます。データとコードを分離し、オブジェクト指向の考え方を具現化。
、Runnableインタフェースを実現し、現在のスレッドにアクセスし、あなたがにThread.currentThread()メソッドを使用する必要があります。継承Threadクラスを、現在のスレッドを取得するためにこれを使用します。

五、Threadクラス開始()とrun()メソッドの違いは何ですか?
start()メソッドは、新しいスレッドが作成されて開始するために使用され、スタートは()内部でrun()メソッドを呼び出し、この効果は直接実行()メソッドの呼び出しが同じではありません。
あなたはrun()メソッドが唯一の元のスレッドに呼び出されるコールすると、新しいスレッドが新しいスレッドを開始します()メソッドを起動し、開始されません。特に注目すべきなのです:2つの呼び出しが同じスレッドオブジェクトの()メソッドを起動することはできません。

第六に、のライフサイクルのスレッド
のJavaは、5つの状態をスレッド:
1.新しい状態(新)を作成します:スレッドオブジェクトが作成されると、それは新しい状態に、です。唯一のJava仮想マシンのメモリの割り当てと初期化することによって。例えば:MyThreadスレッド新しい新しい= T();
2.準備状態(Runnableを):ときstart()メソッド(t.start();)オブジェクトを呼び出すスレッド、レディ状態に、すなわちスレッド。Java仮想マシンのメソッド呼び出しスタックとプログラムカウンタを作成するための準備の状態を通し、単にこのスレッドは準備ができて述べたように、任意の時点で実行されるようにスケジュールCPUを待って、このスレッドは実行されませんでした。
3.ファイル名を指定して実行状態(実行中):CPUのスレッドのスケジューリングは、レディ状態で起動され、実行run()メソッドは、この時間は本当にランモードに入るのスレッドを実行することができました。注意:スレッドの状態が動作状態へのアクセスの唯一の手段である、つまり、スレッドの実行を実行している状態に入るために、すべての最初は、即応の状態でなければなりません。
4.ブロックされた(ブロック):何らかの理由でスレッドを実行しています一時的にそれがレディ状態になるまで、ブロックに、実行を停止し、この時間はCPUを使用する権利を放棄し、再び状態を実行するためにCPUに呼び出されるチャンスがあります。ブロッキングが発生する理由に応じて、ブロックされた状態の3種類に分けることができる:
ブロッキング待機-スレッドが待機状態のブロックに入るように、実行のスレッドは、状態操作()メソッドを待って、JVMは、プールにスレッドを待機します。
-同期ブロック(ロックが他のスレッドによって占有されているので)、同期同期ロックを獲得するスレッドが、それは同期ブロッキング状態になり失敗します。
ブロックされた-スレッドの睡眠を(呼び出すことによって)または(結合)またはI / O要求を発行し、ブロックされた状態に通します。睡眠()タイムアウト、参加()またはタイムアウトは、スレッドの終了を待つか、I / O処理が再びレディ状態に、スレッドを終了しました。
5.死状態(デッド):スレッドのrun()メソッドが原因上やrun()メソッド、ライフサイクルの糸端のうち、異常に実行します。ときにメインスレッド、他のスレッドは影響を受けません。
制御方法の七、Javaスレッド
1は、コールが実行前に完了すると、スレッドAに別のスレッドBの方法を参加の実行を待つことになるスレッドBをスレッド化する場合、スレッドは、スレッドオブジェクトのメソッド呼び出しで参加する参加します。

2. 守护线程(Daemon Thread) Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 。 用户线程即运行在前台的线程,而守护线程是运行在后台的线程。 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普通、非守护线程仍然运行时才需要,比如垃圾回收线程就是一个守护线程。当VM检测仅剩一个守护线程,而用户线程都已经退出运行时,VM就会退出,因为没有如果没有了被守护这,也就没有继续运行程序的必要了。如果有非守护线程仍然存活,VM就不会退出。 守护线程的特征:如果所有前台线程都死亡,后台线程会自动死亡。 守护线程并非只有虚拟机内部提供,用户在编写程序时也可以自己设置守护线程。用户可以用Thread的setDaemon(true)方法设置当前线程为守护线程。 虽然守护线程可能非常有用,但必须小心确保其他所有非守护线程消亡时,不会由于它的终止而产生任何危害。因为你不可能知道在所有的用户线程退出运行前,守护线程是否已经完成了预期的服务任务。一旦所有的用户线程退出了,虚拟机也就退出运行了。 因此,不要在守护线程中执行业务逻辑操作(比如对数据的读写等)。 另外有几点需要注意:

1、setDaemon(true)必须在调用线程的start()方法之前设置,否则会跑出IllegalThreadStateException异常。
2、在守护线程中产生的新线程也是守护线程。  
3、 不要认为所有的应用都可以分配给守护线程来进行服务,比如读写操作或者计算逻辑。 
  1. スレッド譲歩(歩留まり)収量は直接のは、現在実行中のスレッドを一時停止させ、Threadクラスを呼び出すことができ、スレッドがブロックされたが、準備完了状態にスレッドされることはありません。収量は同レベルのスレッド、そうでない場合に待機する権利の実装におけるCPUスレッドの同じレベルにCPUの実行を行い、スレッドが続いています。

八、スリープ()メソッドおよび収率()メソッドとの間の差である
、現在のスレッドを一時停止するスリープ()メソッドは、他のスレッドは、実行する機会を与える他の優先順位のスレッドを気にしないであろう。しかし、収率()メソッドは、同じ優先順位を与えますまたは優先度の高いスレッド実行の機会。
ブロッキング時間がレディ状態に移行されるまで、スリープ()メソッドは、ブロックされた状態(遮断状態)にスレッドであろう;及び収率()メソッドがブロック状態にスレッドない、単にレディ状態に現在のスレッドを強制します。スレッドが一時停止した後に収率()メソッドを呼び出すことが完全に可能で、プロセッサリソースへの即時アクセスが再び行われます。
睡眠()メソッドの宣言は例外:InterruptedException例外がスローされますので、どちらかの睡眠()メソッドを呼び出して、明示的にスロー宣言、例外をキャッチし、そして収量()メソッドは、例外がスローされた宣言されていません。
睡眠()メソッドは、収率()メソッドよりも移植性があり、一般的に推奨されていません利回り()メソッドは、同時スレッドの実行を制御します。
九、なぜThreadクラスの睡眠()および収率()メソッドは静的ですか?
スリープ(Threadクラス)と収率()メソッドは、現在実行されているスレッドで実行されます。だから、待機状態で他のスレッド上でこれらのメソッドを呼び出すことは無意味です。彼らは、現在実行中のスレッドで作業することができ、およびプログラマが他の非実行中のスレッドでこれらのメソッドを呼び出すことができると信じて誤って避けること。今現在のスレッドのみを眠ることができ、実現しています。現在のスレッドが自発的である。睡眠をしてみましょう()メソッドはインスタンスになり、現在のスレッドは、デッドロックなどの問題の多くを紹介します別のスレッド、マルチスレッドをスリープ状態に直接することができます。破壊()、(一時停止)、 ()を停止、再開() これらのインスタンスの方法は、(非推奨)推奨されていません。これは、何?現在のスレッドのみとなのgetXXX()、isXXX(のような、より緩やかなオペレーティングインスタンスメソッドの一部にのみ静的メソッドを()生き残っ 、)(参加収量() ようにと。

テン、睡眠とwaitメソッドメソッドの違いは?
スリープメソッドが静的で、waitメソッドは非静的メソッドです。
自分で投稿する時の睡眠方法は、それが通過する(すべて)メソッドに通知他のスレッドによってでなければならない、「ウェイクアップ」が、待つことができない「目を覚まします。」
睡眠方法は通常、スレッド、一般的な待機を使用して、データベース接続を待っているように、リソースを待たずにあるブロックで使用されています。
XIのセキュリティスレッド
スレッドの安全性の問題は、実際には、矛盾にこの共有リソースを引き起こす可能性があり、共有リソースへのマルチスレッド環境にアクセスすることを指します。そのため、スレッド安全性の問題を回避するには、マルチスレッド環境この共有リソースへの同時アクセスを避ける必要があります。

XII同期ブロック
のシンクブロックフォーマット:

 synchronized (obj) {             
    //...
 }

これは、objがオブジェクトロックなので、ロックが不可欠であるとして、その一つのオブジェクトを選択してください。通常の状況下では、この共有リソースオブジェクトがロック対象として選択されます。いつでも、一つだけのスレッドがオブジェクトをロックするためにロックを取得することができ、他のスレッドがロックを取得することはできません、あなたはそれを変更することはできません。場合、同期コードブロックが終了すると、スレッドはロックオブジェクトのロックを解除します。このように、我々は、いずれかの時点での同時スレッドが唯一のスレッドがスレッドの安全性を確保するために、共有リソース(クリティカル領域)を変更するためにコード領域に入ることができるようにすることができます。

XIII同期メソッド
このメソッドは同期メソッドと呼ばれるようにアクセスできる共有リソースのメソッドの定義は、synchronizedキーワードは修正追加します。この方法は、単純に現在の方法自体に物体オブジェクトをロックするロックであると理解することができます。マルチスレッド環境、この方法を実行する、すべての最初の(高々一つのスレッドだけが得ることができますが)、この同期ロックを取得する必要があり、スレッドはこの同期メソッドの実装を完了したときにのみ、ロックを解除し、他のスレッドが持っていますあなたはその上で、この同期ロックを取得してもよく、...

 public synchronized void a() {        
     // ....
 }

スレッドセーフなクラス変数は、以下の戦略を使用することができますプログラムによってもたらされるマイナスの影響を軽減するために、セキュリティ手順を犠牲にして、プログラムの効率を低下させることに基づいています: - すべてのメソッドが同期しているため、のみをクラススレッドセーフないでください。リソースの競合は、同期の方法を変更します。 - 変数の動作環境には2つのカテゴリがある場合:スレッドセーフバージョンおよびスレッドセーフバージョン:シングルスレッドとマルチスレッド環境が、それは変数のカテゴリの2つのバージョンを提供する必要があります。シングルスレッド環境のパフォーマンス、マルチスレッド環境でのスレッドセーフバージョンの使用を確保するために、スレッドセーフなバージョンを使用してください。

それは、同期モニターロックを解除します第四に、?
プログラムが明示的に同期モニターのロックを解除しない、スレッドロックは、次のように放出されてもよい:A、スレッド同期方法、実行するための同期コードライブラリの終了は、同期監視Bを解放することができ、時にスレッド同期コードライブラリ、メソッドBREAK遭遇は、スレッドが未処理のエラー同期コードライブラリ、同期方法、例外が発生したときに、解放することができます実行終了コードCを返す、と、スレッド、コードの最後には、同期モニターDを解放することができます原因同期コードベース、同期方法、監視対象の待機を同期させるためのプログラム実行方法では、同期モニターの解放を停止する方法を引き起こします

次の場合は、同期モニタを解放されません:
スレッド同期コードライブラリ、同期メソッドの実行は、プログラムが現在のプログラムを一時停止するのThread.sleep()/ Thread.yield()メソッドを呼び出すときA、現在のプログラムが同期監視を解放しませんデバイス
スレッド同期方法を実施B、ときに同期コードライブラリ、他のスレッドがこのスレッドのメソッドを呼び出すスレッドが中断された中断、スレッドは、同期モニタを解放しません。再開、中断使用を避ける注意
XV同期ロック(ロック)は
、一般的に考えられている:ロックは、より広範なロック操作を提供ロックと同期方法よりも柔軟な構造とコードブロックを同期化、そこに大きな違いがあり、複数のサポートすることができロック条件オブジェクト制御の共有リソースツールへのアクセスに複数のスレッドです。通常、ロックは共有リソースへの排他的アクセスを提供し、あなただけのオブジェクトのロックをロックするスレッドを1つ持つことができ、スレッドが訪問はロックオブジェクトを取得する共有リソースが先行されなければならない開始します。ReadWriteLock(読み書きロック)、スレッドセーフ制御が一般的にReentrantLockの(再入可能ロックを)使用されます。ただし、いくつかのロックは、次のような共有リソースへの同時アクセスをサポートしています。ロックオブジェクトはロックが解除され、ロックを使用して表示することができます。

class C {
        //锁对象
        private final ReentrantLock lock = new ReentrantLock();
        ......
        //保证线程安全方法
        public void method() {
            //上锁
            lock.lock();
            try {
                //保证线程安全操作代码
            } catch() {
 
            } finally {
                lock.unlock();//释放锁
            }
        }
    }

ロックオブジェクト、同期を使用してロックし、ロックが解除されたときに、最終的に実行することができます保証に注意を払うのロックを解除します。ロック同期するときにのみ示されている方法を使用してロックを呼んで、非常によく似たロックと同期を使用してください。動作モード、それだけで一つのスレッドのオペレーティングリソースを確保することができます同期方法を使用して同期するときと、暗黙のうちにある「 - - >アクセス>ロックを解除ロックされた」として、同期モニターとして現在のオブジェクトを使用します。同期方法と逆の順序で解放されなければならないリソースの競合、暗黙の同期モニタ、及び強制ロックとブロック構造に表示されるロックを解除し、ロックの複数を得るに関連付けられた同期ブロックすべてのロックを取得するときと同じ範囲内のすべてのリソースを解放する必要があります。ロックが同期方法および他の特徴同期コードライブラリは、のtryLock方法は割り込みのために非ブロック構造が含まれていない提供ロックlockInterruptibly()メソッドと同様に、ロック・タイムアウトのtryLock(長い、TIMEUNIT)メソッドを取得するために失敗を取得しようとしています。ReentrantLockのは、リエントラント、スレッドが再びReentrantLockのをロックすることができますロックされたことを意味し、ReentrantLockのオブジェクトが(ロックする各呼び出しの後、ネストされた呼び出しのスレッドのロック方法を追跡するカウンタを維持する)ロックをしなければならない持っています表示コールロック解除()と同じ方法で保護されたコードの別の部分が保護ロックと呼ばれることができるように、ロックを解除します。

XVIのデッドロック
モニタが同期しているとき、2つのスレッドが互いのデッドロックを待つ発生し、JVMは、私たちが自分自身に対処するか、デッドロックを回避する必要がデッドロックに対処するための措置を取りませんでした。デッドロックすると、全体のプロセスは珍しくもエラーとプロンプトでもないですが、スレッドがブロックされて、続行できません。Javaはスレッドを中断するために、このメソッドを使用することはお勧めしませんので、簡単に、デッドロックにつながることができThreadクラスを一時停止するので。リファレンスはhttp://ifeve.com/deadlock/よりデッドロック状態を学びます。コードのほとんどは、デッドロックは、コード内で長時間隠し珍しい条件を待た発生し、それでも小さな確率事象は、それが壊滅的な被害を引き起こす可能性があり、デッドロックしがちではありません。デッドロックは困難な作業である避け、デッドロックを避けるために次のガイドラインに従ってください。

 1、只在必要的最短时间内持有锁,考虑使用同步语句块代替整个同步方法;
 
 2、尽量编写不在同一时刻需要持有多个锁的代码,如果不可避免,则确保线程持有第二个锁的时间尽量短暂;
 
 3、创建和使用一个大锁来代替若干小锁,并把这个锁用于互斥,而不是用作单个对象的对象级别锁;

おすすめ

転載: blog.csdn.net/qq_32662595/article/details/84850304
おすすめ