スレッドを理解します
プロセスは、システムは、プロセスの実行、プロセスの終わりから作成されたプログラムを実行して、メモリ内で実行されるアプリケーションです。
スレッドは、単位実行処理で、現在のプロセスは、プログラムの実行、プロセス内の少なくとも1つのスレッドの原因です。
マルチスレッドを同時実行(複数のタスクを実行するために同じ時間)によって特徴付けられ、それは実際に走行速度を増加させないが、運用効率を向上させることができ、より高いCPU使用率を可能にします。
スレッドのスケジューリングについては、タイムシェアリングのスケジューリングやプリエンプティブスケジューリングに分け。
- プリエンプティブスケジューリングモード、優先度の高い、優先度のスレッドの優先利用、CPUのスレッドを設定します。
- タイムシェアスケジューリング、すべてのスレッドがCPUを使用してターンを取る、時間の平均配分各スレッドがCPUを占有。
マルチスレッドは1.Java達成され、
Javaのマルチスレッドは、2つの方法で実装さ:
- Threadクラスを継承し、実行するためのスレッド・オブジェクトを作成するには、runメソッドをオーバーライドします。
- Runable定義されたインタフェースの実装クラスとrunメソッドオーバーライドインタフェース(実行のスレッド)。実行のスレッドのみ、実行に渡されたスレッドオブジェクトとしてrun()メソッドを実装含む実行可能なクラス。
Threadクラスは利点を継承するよりも、Runnableを実装します。
- 同じプログラムコードのための複数のスレッドが同じリソースを共有することができます。
- Javaで単一継承の制限を回避するには。
- 操作デカップリング、コードが複数のスレッドで共有することができ、プログラムの堅牢性を増加させ、そして独立のコードを通します。
- スレッドプールは、だけでなく、直接の継承Threadクラスには、スレッドにRunableまたは呼び出し可能なクラスを達成することができます。
コンストラクタ:
- 公共のスレッド():新しいThreadオブジェクトを割り当てます。
- 公共のスレッド(文字列名):新しいスレッドオブジェクトに指定された名前を割り当てます。
- 公共のスレッド(Runnableを目標):指定されたターゲットを持つ新しいThreadオブジェクトを割り当てます。
- 公共のスレッド(Runnableをターゲット、文字列名):指定された目標に、新しいスレッドオブジェクトを割り当て、名前を指定します。
一般的な方法:
- 公共の文字列のgetName():現在のスレッドの名前を取得します。
- 公共ボイドスタートは():実行を開始するには、このスレッドを起こし、Java仮想マシンは、このスレッドのrunメソッドを呼び出します。
- ます。public void実行():ここで定義されたコードを実行するために、このスレッドのミッション。
- パブリック静的ボイド睡眠(長いミリ):スレッドが現在、(一時的に実行を停止)一時停止する、指定されたミリ秒数を実行しています。
- パブリック静的スレッドcurrentThreadは():現在実行中のスレッドオブジェクトへの参照である返します。
:によって実装プロセスを理解するために、次のコード
// THEAD達成継承し たクラスを MyThead 拡張スレッド{ 公共MyThead(文字列名){ スーパー(名); } @Override 公共 無効RUNを(){ System.out.printlnは( "私はスレッドをだ" + のgetName()); } } パブリック クラスTestThread { 公共 静的 ボイドメイン(文字列[]引数){ // スレッドオブジェクト作成 MyThead MT = 新しい新 MyThead( "M" ); //は、新しいスレッド開く mt.startを(); のSystem.out.printlnを(「私はメインスレッドです」); } }
// 、Runnableを達成するためのrunメソッドオーバーライドする クラスを MyRunable 実装のRunnable { @Override 公共 ボイドラン(){ System.out.printlnは( "私はスレッドだ" + にThread.currentThread()のgetName()); } } パブリック・ クラスTestRunableは、 { 公共 静的 ボイド(文字列[]引数)は、メイン{ // オブジェクトMyRunable作成 MRのMyRunable = 新しい新しいMyRunableを(); //は、スレッドオブジェクトを作成 スレッドTは= 新しい新しい(MR、 "T"のスレッド); // スレッド実行 t.startを(); System.out.println( "私はメインスレッドです" ); } }
2.スレッド同期
複数のスレッドを使用する場合は、同じリソースにアクセスし、スレッド内のリソースを変更し、スレッドの安全性の問題が発生します。
// Runnableを達成するためのrunメソッドオーバーライドする クラスを MyRunable 実装のRunnable { プライベート int型の A = 10 ; @Override 公共 無効実行(){ ながら、(A> 0 ){ 試み{ のThread.sleep( 10 ); } キャッチ(InterruptedExceptionあるE) { e.printStackTrace(); } A - = 1 ; のSystem.out.println( "スレッド" +にThread.currentThread()のgetName() + " の操作の値" + A); } } } パブリック クラスTestRunable { 公共 静的 ボイドメイン(文字列[]引数){ // オブジェクトMyRunable作成 MRのMyRunable = 新しい新しいMyRunableを(); //は、スレッドオブジェクトを作成 スレッド= T1 新しい新しい(MR、「T1」のスレッド)、 スレッドT2 = 新しい新(氏の、 "T2"スレッド); スレッドT3 = 新しい新しいスレッド(氏の"T3" ); // スレッド実行 t1.start(); t2.start(); t3.start(); } }
複数のスレッドは、変数を操作するため、異常値が得られること(-1発生してはなりません)。
スレッドの安全性の問題は、その後、あなたがスレッドの同期を使用する必要があり、操作によるグローバル変数を変更するために、複数のスレッドによって引き起こされます。
同期原理スレッド:
リソースを操作するスレッドが、他のスレッドが動作するように許可されていない場合は、データの同期を確保します。
Javaは、スレッドの同期を実装するには3つの方法を提供します。
- 同期コードブロック:synchronizedキーワードは、ブロックのプロセスで使用することができ、ブロックは、コードへの排他的アクセスを追加します。
-
同期方法:同期修飾法を使用して。このメソッドの実装でスレッドは、他のスレッドがブロックされています。
- ロックロック:また、同期ロック、ロックとして知られており、方法のロックを解除。
シンクブロック:
// 实现Runnableを、重写実行方法の クラス MyRunableは実装したRunnable { プライベート int型の A = 10 ; // 同步锁 オブジェクトロック= 新しいオブジェクト(); @Override 公共 のボイドの実行(){ ながら、(真){ 同期(ロック){ 場合(A> 0 ){ しようと{ のThread.sleep( 50 )。 } キャッチ(InterruptedExceptionある電子){ )(e.printStackTraceします。 } A - = 1 ; のSystem.out.println( 。"スレッド" +にThread.currentThread()のgetName() + " の操作の値" + A); } } } } } パブリック クラスTestRunable { 公共 静的 ボイドメイン(文字列[]引数){ // 作成するオブジェクトMyRunable 氏=のMyRunable 新しい新しいMyRunable(); //は、スレッドがオブジェクト作成 スレッド= T1 新しい新しいスレッドを(MRの、 "T1" )。 スレッドT2 = 新しいですスレッド(氏の、「T2」を); スレッドT3 = 新しいスレッド(MR、 "T3" )。 // 运行线程 t1.start(); t2.start(); t3.start(); } }
同期方式:
//实现Runnable,重写run方法 class MyRunable implements Runnable{ private int a = 10; @Override public void run(){ while (true) { method1(); } } //同步方法 public synchronized void method1(){ if (a > 0){ try{ Thread.sleep(50); }catch (InterruptedException e){ e.printStackTrace(); } a -= 1; System.out.println("线程"+Thread.currentThread().getName()+"操作了a,a的值为"+a); } } } public class TestRunable { public static void main(String[] args){ //创建 MyRunable对象 MyRunable mr = new MyRunable(); //创建线程对象 Thread t1 = new Thread(mr,"t1"); Thread t2 = new Thread(mr,"t2"); Thread t3 = new Thread(mr,"t3"); //运行线程 t1.start(); t2.start(); t3.start(); } }
Lock锁包含两个方法:
- public void lock() :加同步锁。
- public void unlock() :释放同步锁。
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; //实现Runnable,重写run方法 class MyRunable implements Runnable{ private int a = 10; //同步锁 Lock lock = new ReentrantLock(); @Override public void run(){ while (true){ //加锁 lock.lock(); if (a > 0){ try{ Thread.sleep(20); }catch (InterruptedException e){ e.printStackTrace(); } a -= 1; System.out.println("线程"+Thread.currentThread().getName()+"操作了a,a的值为"+a); } //释放锁 lock.unlock(); } } } public class TestRunable { public static void main(String[] args){ //创建 MyRunable对象 MyRunable mr = new MyRunable(); //创建线程对象 Thread t1 = new Thread(mr,"t1"); Thread t2 = new Thread(mr,"t2"); Thread t3 = new Thread(mr,"t3"); //运行线程 t1.start(); t2.start(); t3.start(); } }
3.线程状态
- NEW:线程创建未启动。
- Runnable:可运行。
- Blocked:锁阻塞。当一个线程获得同步锁时,其他线程会被阻塞,直到获得同步锁。
- Waiting:无限等待。当一个线程进入Waiting状态后,会无限等待,直到其他线程调用notify或者notifyAll方法唤醒(线程通信)。
- TimedWaiting:计时等待。当一个线程调用sleep方法时,程序会进入计时等待,直到时间结束。
-
Teminated:被终止。run方法未正常退出而死亡。
温馨提示
- 如果您对本文有疑问,请在评论部分留言,我会在最短时间回复。
- 如果本文帮助了您,也请评论关注,作为对我的一份鼓励。
- 如果您感觉我写的有问题,也请批评指正,我会尽量修改。