Javaの研究ノート:multithreading1

I.概要とプロセスとスレッドの意義

1、工程
A、概要:プロセスは、プログラムが、システムリソースの割り当てと呼ばれる独立した単位を実行していることです。各プロセスは、独自のメモリ空間とシステムリソースを持っています。
B、マルチプロセスを意味する:単一プロセスコンピュータは一つのことを行うことができます。音楽(音楽コース)を聴きながら、ゲーム(ゲーム処理)を再生しながら、そして、我々は我々が持っているので、一般的なオペレーティングシステムは、マルチプロセスのオペレーティングシステムです、今のコンピュータ缶です。あなたは、同じ時間帯に複数のタスクを実行することが可能となります。マルチプロセスの役割は、実行速度を向上させますが、CPUの使用率を向上させることがありません。
2、スレッド
、概要:彼らは、プロセス内で複数のタスクを実行し、すべてのタスクは、我々はスレッドとして見ることができるということができます。スレッドは、CPU利用プログラムの基本単位です。
Bは、意味マルチスレッド:マルチスレッドの役割は、実行速度を向上させるためにされていませんが、アプリケーションの使用量が増加します
C、平行と同時
並行で複数のプログラムを実行している間の時間を意味し、
平行は、同時に複数のプログラムを実行する時点を指します。

第二に、マルチスレッドの実装

スレッドは、プロセスが存在に依存しているので、私たちは最初のプロセスから作成する必要があります。プロセスは、システムによって作成されたので、私たちは、プロセスを作成するために、システム機能を呼び出して行く必要があります。私たちは直接、マルチスレッドプログラムを実装する方法がありませんので、しかし、Javaは、直接システム関数を呼び出していません。しかし、Javaはマルチスレッドプログラムを実装するために/ C ++ C書かれたプロシージャを呼び出すために行くことができます。C / C ++、当社の使用のためのクラスを提供し、プロセスを作成するために、システム機能を呼び出し、その後、Javaのことで、このようなものを呼び出すために、とします。私たちは、マルチスレッドプログラムを達成することができます。
1、マルチスレッドの実装:
A:トレッド文のサブクラスは、サブクラスは、Threadクラスのrunメソッドをオーバーライドします。
オープンスレッドにする方法:startメソッドが呼び出され、スレッドオブジェクトを開いてスレッドを繰り返すことはできません
オーバーライドrunメソッド:メソッド内のコードを実行しますが、その実行のコードスレッドを作り、スレッドが実行できるようにすることです、あなたは内部のrunメソッドに記述する必要があります

 class MyThread extends Thread{
            @Override
            public void run() {
                //一般run方法里面,放的是耗时的操作
                for (int i = 0; i < 100; i++) {
                    String name = this.getName();
                    System.out.println(name+"==="+i);
                }
            }
        }
    public class MyTest {
        public static void main(String[] args) {
            MyThread th1 = new MyThread();
            MyThread th2 = new MyThread();
            th1.start();
            th2.start();
        }
    }

B:スレッドオブジェクト名を取得および設定

  • 公共の最終文字列のgetName()//スレッド名を取得します
  • 公共の最終無効のsetName(文字列名)//スレッド名を設定します。

C:スレッドのスケジューリングとスレッドの優先順位を取得および設定

  • 実行のスレッドは、実行CPUをCPUの執行力をつかんでいくつかの点でどのスレッド、ランダムであり、

  • スレッドのスケジューリングは、2つのモデルがあります:時分割スケジューリングやプリエンプティブスケジューリングモデルがあります。Javaスレッドのスケジューリングはプリエンプティブモデルです。

  • タイムシェアスケジューリングモデル:すべてのスレッドがCPUを使用してターンを取る使用する権利、各スレッドが消費するCPU時間のスライスの平均配分

  • プリエンプティブモデル:優先度の高いスレッドのCPUを優先し、比較的多くのスレッドの優先順位は、優先度の高いスレッドのランダムな選択と同じになる場合は、CPU時間を取得します

  • 設定し、スレッドの優先度を取得します:

  • 公共の最終int型getPriority()// GET優先スレッド

  • 公共の最終無効setPriorityを(int型newPriority)//設定したスレッドの優先順位

注: 時々 、私たちは、スレッド指定された優先順位を設定する必要がありますが、スレッドがあるため、このスレッドのスレッド優先順位の大きさの、優先度の高いスレッドの実行に応じていないだけで、CPUの増加によって実行される確率を表しますしかし、我々はすべてのランダムなマルチスレッドことを知っているので、時には一度か二度実行するには、問題を説明することはできません。
図2に示すように、マルチスレッド実装II:
Statementクラスパラメータがスレッドを渡される実装が実行可能インタフェース、クラスオーバーライドrun()メソッドは、スレッドオブジェクトを作成し、インタフェースサブクラスオブジェクトをサブクラスオブジェクトインタフェースを作成すること、スレッドを開始します。

class MyRunable implements Runnable{ 
    @Override
    public void run() {
        //需要线程执行代码
        for (int i = 0; i < 100; i++) {
            String name = Thread.currentThread().getName();
            System.out.println(name+"==="+i);
        }
    }
}
public class MyTest {
  public static void main(String[] args) {
        //Thread(Runnable target)
        //分配新的 Thread 对象。
        //Thread(Runnable target, String name) 参数2 线程名字
        MyRunable myRunable = new MyRunable();
        Thread th1 = new Thread(myRunable,"线程A");
        Thread th2 = new Thread(myRunable,"线程B");
        th1.start();
        th2.start();
   }
}

3、マルチスレッドの実装3:
Threadクラスに渡されたパラメータが作成されるように、パラメータがFutureTaskに渡すよう実装呼び出し可能インターフェースは、オブジェクトのクラスFutureTask呼び出し可能インターフェースのサブクラスを作成することにクラスを作成します。

public class MyCallable implements Callable<Integer> {
    //让线程来执行的方法
    @Override
    public Integer call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"==="+i);
        }
        return 100;
    }
}
    public class MyTest {
        public static void main(String[] args) throws Exception {
            MyCallable myCallable = new MyCallable();
            //FutureTask 这个是Runable接口的子类, 他可以封装一个Callable 任务
            FutureTask<Integer> task = new FutureTask<>(myCallable);
            Thread th1 = new Thread(task);
            th1.start();
            Integer integer = task.get();   //get()方法,可以获取线程执行完之后返回的结果
            System.out.println(integer);
        }
    }

注: ()メソッドの呼び出しおよび実行()を実行するスレッドになっている、違いは、結果を返すためにコールを実行していると、このメソッドは例外をスローすることができます。実行()スレッドの実行を使用すると、例外をスローすることはできません、結果は返されません、以上です。
図4に示すように、一般的な方法スレッド

  • パブリック静的スレッドcurrentThread()は、現在実行中のスレッドオブジェクトへの参照である返します。
  • 公共の静的な無効スリープ(長いミリ) ; スレッドのスリープ
  • スレッドは、次のとおりです。公共の最終ボイドが参加(); 以下を実行しているスレッド待ち、他のスレッドは、次の行Chengkaiチーを追加し、開始することができます。
  • パブリック静的ボイド収率(); スレッド礼譲、現在実行中のスレッドオブジェクトを一時停止し、他のスレッドをオンに
  • 公共の最終のボイドは、setdaemon(ブール) ; ユーザスレッドが死亡した後、またすぐにデーモンスレッド死亡したときにデーモンスレッドを設定するには、メインスレッドはユーザスレッドです
  • 公共の最終無効停止(); スレッドが死の状態であるように強制的にスレッドを停止
  • 公共のボイド割り込みは(); 中断されたスレッドをブロック

5、セキュリティスレッドの
三つの条件に沿って、A、データのセキュリティ問題

  • :マルチスレッドされていません
  • B:そこに複数のスレッドのデータを共有しています
  • C:この操作データには、複数のif文

B、データセキュリティの問題解決するために
、それは上記の3つの基準を満たしているので、その後、私達はちょうど私たちは、この問題を解決することができ、この標準を破壊する、プログラムの問題をAに。そして、上記の基準、Bは、中断されていません我々は唯一の処理Cを行うことができますので、キーがどのように対処する?我々は複数の文を入れて共有データの操作1つのスレッドがとき言うことです、待機状態では、この全体の時間、他のスレッドを実行したときに、全体として見ることが場合ですスレッド全体を実行したとき、他のスレッドを実行することはできません。
B、基本的な考え方:プログラム・ノー環境のセキュリティ問題を聞かせていません。共有データへのコード複数のステートメントの動作はいつでも唯一つのスレッドが実行できるように、ロックアップ。同期コードブロックが必要です:
C、フォーマット:

synchronized(对象){//不能在括号里直接new 对象 new 了 就没效果
    			要被同步的代码 ;
    		}
注意:	这个同步代码块保证数据的安全性的一个主要因素就是这个对象
	    这个对象要定义为静态成员变量 才能被所有线程共享
    	这个对象其实就是一把锁.

いずれかのオブジェクト:シンクブロックは、オブジェクトロック
これは:同期方法ロックオブジェクトの
ロックされたオブジェクトの静的な同期方法を:その現在のクラスのバイトコード・ファイルオブジェクトに対応します

C、同期の利点:同期は、マルチスレッドのセキュリティ問題を解決するために起こります。
D、欠点の同期:スレッドが非常に長い時間があるときに、裁判官への各スレッド同期ロックするので、これは非常にリソース集約型で、効果的にプログラムの効率を低下させるだろう。
展開し
、Javaプログラミングでは、多くの場合、同期を使用する必要があり、おそらく最も使用は、synchronizedキーワードは、ロックの概念に関連しているため、synchronizedキーワードですので、関連する知識のロックのいくつかを理解することが第一。

  • Javaは組み込みのロック:各Javaオブジェクトを同期ロックとして使用することができ、これらのロックは、ロックを構築します。スレッドは、あなたがsynchronizedブロックまたはメソッド解放したロックを終了すると、自動的に、ロックを取得するsynchronizedブロックまたはメソッドに入ると。ロックを取得する唯一の方法は、このブロックまたはシンクロック保護法に組み込まれています。
  • Javaがビルトインされている場合、内蔵のロックのホールドを取得するために、スレッドAスレッドBの試み一つだけのスレッドが、ロックを取得することができ、最大で意味しているロックミューテックス、スレッドはロックBを解放するまで、スレッドAが待たまたはブロックしなければなりませんスレッドがロックBを解放しない場合、スレッドは永遠に待機します。
  • Javaオブジェクトとロックをロック:Javaクラスとオブジェクトは、ラッチロックは、実質的に均一であり、内蔵のロックの概念ロックは、しかし、実際には2つのロックされたオブジェクトがロックオブジェクトのインスタンスである、非常に異なっています方法、またはオブジェクトクラスのインスタンスでは、クラスオブジェクトまたはクラスの静的メソッドのクラスのロックです。私たちは、オブジェクトインスタンスのクラスは、多くのことができることを知っているが、各クラスが一つだけクラスオブジェクト、異なるオブジェクトのインスタンスが互いに干渉オブジェクトのロックを持っていますが、各クラスは1つのクラスのロックを持っています。しかし、一つのことは、実際には、概念ロックちょうど何かのように、本物の、私たちだけがロックインスタンスメソッドと静的メソッドの違いを理解するために使用されているが存在しないことに注意しなければなりません。

例えば:

 某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。
 分析:
 	a: 三个窗口其实就是3个线程
  	b: 定义票的数量100张
  	c: 创建线程对象,启动线程. 每卖一张这个票数应该--
class CellRunable implements Runnable{
   static int piao=100;
   static Object obj=new Object();
   @Override
   public void run() {
      while (true) {
      //只要任意一个线程,进入了同步代码块了以后,就会锁上(这个线程就会持有这把锁),其他线程,获取不到这个锁就处于阻塞状态
      //java 中这种内置的锁,我们称之为互斥锁
        synchronized (obj){ //同步代码块 锁对像 ,可以传任意一个对象 ,注意多个对象要共享一把锁
        //进来之后 说白了就是一个单线程环境
           if (piao > 0) {
              try {
                  Thread.sleep(50);
              } catch (InterruptedException e) {
                  e.printStackTrace();
               }
       System.out.println(Thread.currentThread().getName() + "正在出售 " + (piao--) + " 张票");
            }
       }
    //出来之后,才会释放锁
    }
  }
}
public class MyTest {
  public static void main(String[] args) {
    //synchronized 效率低  耗费性能
    CellRunable cellRunable = new CellRunable();
    Thread th1 = new Thread(cellRunable);
    Thread th2 = new Thread(cellRunable);
    Thread th3 = new Thread(cellRunable);
    th1.setName("窗口1");
    th2.setName("窗口2");
    th3.setName("窗口3");
    th1.start();
    th2.start();
    th3.start();
  }
}
公開された24元の記事 ウォン称賛11 ビュー2050

おすすめ

転載: blog.csdn.net/weixin_43791069/article/details/86603416