ホームページ  >  記事  >  Java  >  スレッド、スレッド作成例チュートリアル

スレッド、スレッド作成例チュートリアル

零下一度
零下一度オリジナル
2017-06-25 09:35:591548ブラウズ

メインスレッド: メインメソッドを実行するスレッドをメインスレッドと呼びます

シングルスレッドプログラム: プログラムはmaniから上から順に実行されます

プログラムはメインメソッドから実行されます。 JVM はメインメソッドを実行し、それを見つけます オペレーティングシステム
CPU への実行パスを開きます
CPU はこのパスを通じてメインメソッドを実行できます
このパスにはメインスレッドという名前が付いています
スレッドメソッドを作成します1. Thread クラスを継承する

実装手順:
1. Thread クラスのサブクラスを作成する
2. Thread クラスの run メソッドを書き換え、スレッドのタスクを設定する
3. Thread クラスのサブクラス オブジェクトを作成する
4. Thread クラスの start メソッドを呼び出して新しいスレッドを開始し、run メソッド
を実行してスレッドの実行を開始します。Java 仮想マシンはスレッドの run メソッドを呼び出します。
その結果、現在のスレッド (メインスレッド) ともう一方のスレッド (run メソッドを実行するスレッド) の 2 つのスレッドが同時に実行されます。
スレッドを複数回開始することは違法です。特に、スレッドの実行が終了した場合、再起動することはできません。

印刷結果にはランダム性があります:
2 つのスレッドを開いて、CPU に適したものを選択してください

好きな人が実行されるため、ランダム性があります
 1 public class MyThread extends Thread{ 2     /* 3      * 2.重写Thread类中的run方法,设置线程的任务 4      * 开启这个线程要干什么事情 5      */ 6     @Override 7     public void run() { 8         for (int i = 0; i < 50; i++) { 9             System.out.println("run..."+i);10         }11     }12 }13     public static void main(String[] args) {14         //3.创建Thread类的子类对象15         MyThread mt = new MyThread();16         //mt.run();//不会开启线程,还是单线程程序17         //4.调用Thread类中的start方法开启一个新的线程,执行run方法18         mt.start();19         20         new MyThread().start();21         22         for (int i = 0; i < 50; i++) {23             System.out.println("main..."+i);24         }25     }


スレッドの名前:
メインスレッド: " main"
開いている他のスレッドの名前: "Thread-0"、"Thread-1"....

スレッドの名前を取得します
1. Thread クラスのメソッド getName
String getName() はスレッドの名前を返しますスレッド 。
2. 現在実行中のスレッドを取得する Thread クラスの static メソッド
static Thread currentThread() は、現在実行中のスレッド オブジェクトへの参照を返します。
スレッドの名前を設定します。
1. Thread クラスのメソッド setName(String name)
void setName(String name) は、パラメータ名と同じになるようにスレッド名を変更します。
2. サブクラスにパラメーター化されたコンストラクターを追加し、親クラス Thread クラスのパラメーター化されたコンストラクターを呼び出し、スレッドの名前を渡し、親クラスにスレッドの名前を付けます (父親が息子に名前を付けます)
Thread(String name ) 新しい Thread オブジェクトを割り当てます。

スレッドモードの作成 - Runnableインターフェースの実装


実装手順:
1. Runnableインターフェースの実装クラスを作成します
2. Runnableインターフェースのrunメソッドをオーバーライドし、スレッドタスクを設定します
3. 実装クラスを作成しますRunnableインターフェースのオブジェクト
4. Threadクラスのオブジェクトを作成し、コンストラクター
Thread(Runnableターゲット)にRunnableインターフェースの実装クラスを渡して、新しいThreadオブジェクトを割り当てます。

5. Thread クラスの start メソッドを呼び出して、run メソッドを実行するスレッドを開始します



Runnable を実装する利点
1. クラスが Thread クラスを継承した後は、他のクラスを継承できないという事実を回避します (単一継承の制限)
2. スレッドタスクの設定はスレッドの開始から切り離されており、スケーラビリティが向上します
実装クラスの役割はスレッドタスクを設定することです
Thread クラスの役割: スレッドを開始することです

利点: 異なる実装を渡すことクラス、実装クラスの書き換え方法が異なり、別のメソッドを呼び出すことができます


スレッドの匿名の内部クラスが使用されます

匿名: no name
内部クラス: 他のクラスの内部に書かれたクラス(メンバーの位置: メンバーの内部クラス、ローカルの位置( inメソッド): ローカル内部クラス)

匿名内部クラスの形式:
新しい親クラス/インターフェイス(){
親クラス/インターフェイスのメソッドをオーバーライドします;
};

マルチスレッド親クラス:
Thread

Runnable
1  new Thread(){2             //重写run方法,设置线程任务3             @Override4             public void run() {5                 for (int i = 0; i < 20; i++) {6                     System.out.println(Thread.currentThread().getName()+":"+i);7                 }8             }9         }


上記のヒープ コードは、サブクラスを作成し、親クラスのメソッドを書き換えるプロセスです

以下と同等です: new MyThread().start();


プログラムにはスレッド セーフティの問題があります: 重複したチケットと存在しないチケットが存在します。 sold

解決策:
1 つ目の方法: 同期されたコード ブロック

を使用できます (ロック オブジェクト) {
共有データにアクセスするコード;
}
注:
は、複数のスレッドで使用されています 同じロック オブジェクトです
//メンバーの位置にロック オブジェクトを作成します (一意であることが保証されています)

 1 Object obj = new Object(); 2      3     @Override 4     public void run() { 5         //让卖票重复执行 6         while(true){ 7          8              * 同步代码块 9              * 程序会频繁的判断锁,获取锁,释放锁,所以会降低速度10              11             synchronized (obj) {12                 if(ticket>0){13                     //为了提高安全问题的概率,让程序睡眠14                     try {15                         Thread.sleep(10);16                     } catch (InterruptedException e) {17                         e.printStackTrace();18                     }19                     //卖票ticket--20                     System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");21                 }22             }23         }24     }
プログラムにはスレッド セーフティの問題があります: 重複したチケットや存在しないチケットが販売されます


解決策:
2 番目のメソッド: 同期メソッド

使用手順:
1. セキュリティ上の問題を引き起こす可能性のあるコードをメソッドに抽出します
2. メソッドに同期されたキーワードを追加します
修飾子 synchronized 戻り値の型 メソッド名 (パラメータ) {
セキュリティ上の問題がある可能性のあるコード;
共有データにアクセスするコード;
}

同期メソッドで使用されるロック オブジェクトは何ですか?
使用されるのはこのクラス オブジェクトです new RunnableImpl()-->Call this

Static同期メソッド、どのロックオブジェクトが使用されていますか?
使用されているのは、このクラスオブジェクトのクラス属性(リフレクション)です
RunnableImpl.class

 1 *@Override 2     public void run() { 3         //让卖票重复执行 4         while(true){ 5             payTicket2(); 6         } 7     } 8      9     10      * 静态的同步方法11      12     public static synchronized void payTicket2(){13         synchronized (RunnableImpl.class) {14             if(ticket>0){15                 //为了提高安全问题的概率,让程序睡眠16                 try {17                     Thread.sleep(10);18                 } catch (InterruptedException e) {19                     e.printStackTrace();20                 }21                 //卖票ticket--22                 System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");23             }24         }25     }26     27     28     29      * 抽取出一个同步方法30      * 快捷键:alt+shift+m31      32     public ynchronized void payTicket1() {33         synchronized (this) {34             //System.out.println(this);//cn.itcsat.demo10.RunnableImpl@6706435             if(ticket>0){36                 //为了提高安全问题的概率,让程序睡眠37                 try {38                     Thread.sleep(10);39                 } catch (InterruptedException e) {40                     e.printStackTrace();41                 }42                 //卖票ticket--43                 System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");44             }45         }46     }

程序出现了线程安全问题:卖了重复的票和不存在的票
*
* 解决方案:
* 第三种方式:使用Lock接口,JDK1.5之后出现的
*
* java.util.concurrent.locks.Lock接口
* 方法:
* void lock() 获取锁。
* void unlock() 释放锁。  
*  接口的实现类:ReentrantLock
*  
* 实现步骤:
* 1.在成员位置创建一个Lock接口的实现类对象ReentrantLock
* 2.在可能出现线程安全问题的代码前,调用lock方法获取锁
* 3.在可能出现线程安全问题的代码后,调用unlock方法释放锁
*
*1.在成员位置创建一个Lock接口的实现类对象ReentrantLock
Lock l = new ReentrantLock();

 1 @Override 2     public void run() { 3         //让卖票重复执行 4         while(true){ 5             //2.在可能出现线程安全问题的代码前,调用lock方法获取锁 6             l.lock(); 7                 if(ticket>0){ 8                     //为了提高安全问题的概率,让程序睡眠 9                     try {10                         Thread.sleep(10);11                         //卖票ticket--12                         System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");13                     } catch (InterruptedException e) {14                         e.printStackTrace();15                     }finally {16                         //3.在可能出现线程安全问题的代码后,调用unlock方法释放锁17                         l.unlock();    
18                     }19                 }20         }

 

以上がスレッド、スレッド作成例チュートリアルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。