JAvaマルチスレッドの3つの構築方法
7913 ワード
java マルチスレッドの3つの構築方法
Threadクラスの継承スレッドクラスの作成 Threadクラスのサブクラスを定義しrun()メソッド を書き換える.は、スレッドオブジェクト を作成するThreadサブクラスのインスタンスを作成する.スレッドオブジェクトを呼び出すstart()メソッドスレッド を起動する
ThreadクラスはObjectを継承しています
Objectクラスはnameオプションを作成し、getName()、setName()メソッドがあります.
Threadを継承するクラスで使用する場合はthis参照のみ
上の2つのサブスレッドとプライマリスレッドはランダムに切り替えられます.また、Threadを継承するクラスを使用しているため、2つのサブスレッドはリソースを共有できません.
start()メソッド呼び出し後は直ちにマルチスレッドコードを実行するのではなく,そのスレッドを実行可能な状態にプログラミングし,いつ実行するかはオペレーティングシステムによって決定される.
Runnableインタフェースを実装してスレッドクラスを作成する Runnableインタフェースの実装クラスを定義し、そのインタフェースのrun()メソッド を書き換える. Runnableインプリメンテーションクラスのインスタンスを作成し、これをThreadのtargetとしてThreadオブジェクトを作成します.このThreadオブジェクトこそ真のスレッドオブジェクトです.
上記の結果は、2つのサブスレッドとプライマリスレッドがランダムに切り替えられますが、共有できるリソースがまったくないため、共有リソースはありません.
start()メソッド呼び出し後は、直ちにマルチスレッドコードを実行するのではなく、オペレーティングシステムによって決定された継承ThreadクラスとRunnableインタフェースを作成する共有リソースの詳細を実行するスレッドプログラミングを実行可能にする
共有に使用できるリソースのみが使用される場合、つまり同じインスタンス化オブジェクトが使用されます.2つの作成方法は、リソースを共有するときに異なります.そうしないと、リソース共有リソースはprivate static修飾子で修飾されません.
private int count=5があったからこそ;共有リソースは1つしかありませんが、これはThreadクラスを継承するサブクラスであり、リソースを共有することはできません.
同じようにprivate int count=15という共通のインスタンス化オブジェクトがあるからこそ,Runnableを実現するクラスがリソースを共有できる.
では、なぜThreadクラスのサブクラスを継承してRunableインタフェースを実現するクラスがリソースを共有する際に異なるのでしょうか.
Javaでは単一継承しかサポートできないため、単一継承の特徴は1つのサブクラスしか継承できないことを意味し、Runnablインタフェース後に多くのクラスと複数のスレッドで1つのリソースを共有できる操作を行うことができる.
CallableとFutureを使用したスレッドの作成
CallableはどうしてもRunnableインタフェースの強化版のように見えますが、CallableにはRunnableのrun()メソッドに相当するcall()メソッドがありますが、機能はさらに強力です.
call()メソッドには戻り値call()メソッドがあり、放出異常を宣言できます.
Callableインタフェースには汎用制限があり,Callableインタフェースの汎用パラメータタイプはcall()メソッドの戻り値タイプと同じである.また、Callableインタフェースは関数インタフェースであるため、Lambda式を使用してCallableオブジェクトRunnableインタフェースを作成することも関数インタフェースであるため、Lambda式を使用してRunnableオブジェクトを作成することもできます Callableインタフェースの実装クラスを作成し、スレッド実行体として、Callable実装クラスのインスタンス を作成するcall()メソッドを実装する. FutureTaskクラスを使用してCallableオブジェクトをパッケージングする.このFutureTaskオブジェクトはCallableオブジェクトのcall()メソッド をパッケージングする. FutureTaskクラスオブジェクトをThreadオブジェクトのtargetとして使用する新しいスレッド を作成して起動する. FutureTaskオブジェクトのget()メソッドを呼び出し、サブスレッド終了後の戻り値 を得る.
Lambda式のCallableとFutureを使用して作成されたスレッド
もし疑問があれば伝言を残してあるいは当駅のコミュニティに行って討論を交流して、読書に感謝して、みんなを助けることができることを望んで、みんなの当駅に対する支持に感謝します!
Threadクラスの継承スレッドクラスの作成
public class Thread extends Object implements Runnable
public class FirstThread extends Thread {
public void run(){
for(int i=0;i<100;i++){
/*
* Thread Object
* Object name getName(),setName()
* Thread this
*/
System.out.println(this.getName()+" "+i);
}
}
public static void main(String[] args) {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==20){
new FirstThread().start();
new FirstThread().start();
}
}
}
}
ThreadクラスはObjectを継承しています
Objectクラスはnameオプションを作成し、getName()、setName()メソッドがあります.
Threadを継承するクラスで使用する場合はthis参照のみ
上の2つのサブスレッドとプライマリスレッドはランダムに切り替えられます.また、Threadを継承するクラスを使用しているため、2つのサブスレッドはリソースを共有できません.
start()メソッド呼び出し後は直ちにマルチスレッドコードを実行するのではなく,そのスレッドを実行可能な状態にプログラミングし,いつ実行するかはオペレーティングシステムによって決定される.
Runnableインタフェースを実装してスレッドクラスを作成する
public Thread()
public Thread(Runnable target)
public Thread(Runnable target,String name)
public class SecondThread implements Runnable {
public void run(){
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
public static void main(String[] args) {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==20){
SecondThread st=new SecondThread();
// new Thread(target,name)
new Thread(st," 1").start();
new Thread(st," 2").start();
}
}
}
}
上記の結果は、2つのサブスレッドとプライマリスレッドがランダムに切り替えられますが、共有できるリソースがまったくないため、共有リソースはありません.
start()メソッド呼び出し後は、直ちにマルチスレッドコードを実行するのではなく、オペレーティングシステムによって決定された継承ThreadクラスとRunnableインタフェースを作成する共有リソースの詳細を実行するスレッドプログラミングを実行可能にする
共有に使用できるリソースのみが使用される場合、つまり同じインスタンス化オブジェクトが使用されます.2つの作成方法は、リソースを共有するときに異なります.そうしないと、リソース共有リソースはprivate static修飾子で修飾されません.
class Thread1 extends Thread{
private int count=5;
private String name;
public Thread1(String name) {
this.name=name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + " count= " + count--);
try {
sleep((int) Math.random() * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
Thread1 mTh1=new Thread1("A");
Thread1 mTh2=new Thread1("B");
mTh1.start();
mTh2.start();
}
}
B count= 5
A count= 5
B count= 4
B count= 3
B count= 2
B count= 1
A count= 4
A count= 3
A count= 2
A count= 1
private int count=5があったからこそ;共有リソースは1つしかありませんが、これはThreadクラスを継承するサブクラスであり、リソースを共有することはできません.
class Thread2 implements Runnable{
private int count=15;
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " count= " + count--);
try {
Thread.sleep((int) Math.random() * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
Thread2 my = new Thread2();
new Thread(my, "C").start();// mt, Thread , mt,
new Thread(my, "D").start();
new Thread(my, "E").start();
}
}
C count= 15
D count= 14
E count= 13
D count= 12
D count= 10
D count= 9
D count= 8
C count= 11
E count= 12
C count= 7
E count= 6
C count= 5
E count= 4
C count= 3
E count= 2
同じようにprivate int count=15という共通のインスタンス化オブジェクトがあるからこそ,Runnableを実現するクラスがリソースを共有できる.
では、なぜThreadクラスのサブクラスを継承してRunableインタフェースを実現するクラスがリソースを共有する際に異なるのでしょうか.
Javaでは単一継承しかサポートできないため、単一継承の特徴は1つのサブクラスしか継承できないことを意味し、Runnablインタフェース後に多くのクラスと複数のスレッドで1つのリソースを共有できる操作を行うことができる.
CallableとFutureを使用したスレッドの作成
CallableはどうしてもRunnableインタフェースの強化版のように見えますが、CallableにはRunnableのrun()メソッドに相当するcall()メソッドがありますが、機能はさらに強力です.
call()メソッドには戻り値call()メソッドがあり、放出異常を宣言できます.
Callableインタフェースには汎用制限があり,Callableインタフェースの汎用パラメータタイプはcall()メソッドの戻り値タイプと同じである.また、Callableインタフェースは関数インタフェースであるため、Lambda式を使用してCallableオブジェクトRunnableインタフェースを作成することも関数インタフェースであるため、Lambda式を使用してRunnableオブジェクトを作成することもできます
public class ThirdThread implements Callable {
public Integer call(){
int i=0;
for(;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
return i;
}
public static void main(String[] args){
ThirdThread tt=new ThirdThread();
FutureTask task=new FutureTask<>(tt);
Thread t=new Thread(task," ");
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==20){
t.start();
}
}
try{
System.out.println(" :"+task.get());
}catch(Exception e){
e.printStackTrace();
}
}
}
Lambda式のCallableとFutureを使用して作成されたスレッド
public class ThirdThread{
public static void main(String[] args){
ThirdThread tt=new ThirdThread();
// Lambda Callable
// FutureTask Callable
FutureTask task=new FutureTask((Callable)()->{
int i=0;
for(;i<100;i++){
System.out.println(Thread.currentThread().getName()+" i :"+i);
}
return i;
});
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" i :"+i);
if(i==20){
new Thread(task," ").start();
}
}
try{
System.out.println(" "+task.get());
}catch(Exception e){
e.printStackTrace();
}
}
}
もし疑問があれば伝言を残してあるいは当駅のコミュニティに行って討論を交流して、読書に感謝して、みんなを助けることができることを望んで、みんなの当駅に対する支持に感謝します!