2、マルチスレッドの実現方式
1、マルチスレッドの主な実現方式:
一つはThreadクラスを継承しRunnableインタフェースを実現することである
2.Threadクラスの継承とRunnableインタフェースの実現の違い: Javaは単一継承方式であるため、スレッドクラスが他のクラスを継承する場合、Threadクラスを継承する方式は使用できないが、Runnableインタフェースを実現する方式 を使用することができる. Threadクラスのrunメソッドは共有できません.例えば、スレッドAはスレッドBのrunメソッドを自分の実行ユニットと見なすことができません.Runnableを使用すると簡単に実現できます.同じRunnableは複数のインスタンスを構築することができるので、一般的にはRunnableはThreadのtask に相当することが理解できます.職責から言えば、Thread類は主にスレッド自身の関連職責と制御を担当し、Runnableは主にスレッド論理の実行ユニット を担当する.
3、スレッド実現のすべての方式はThreadクラス を継承する. Runnableインタフェース を実装 Callableインタフェースを実現し、FutureTaskにより包装 を行う.匿名内部クラス を使用 Lambda式 を使用スレッドプール を使用タイマー を使用
3.1.Threadクラスの継承
3.2、Runnableインタフェースを実現する
3.3、Callableインタフェースを実現し、FutureTaskで包装する
3.4、匿名内部クラス
匿名内部クラスにも様々なバリエーションがあり、これら3つの方法は匿名内部クラスを用いて暗黙的にインスタンス化することができる.
匿名の内部クラスの利点は、クラスを追加的に定義する必要がなく、コードの可読性が悪いことです.
3.5、Lambda式
Runnableは@FunctionalInterface注記で修飾され、インタフェースには1つの方法しかありません.
3.6、スレッドプール
3.7、タイマー
TimerTaskはRunnableインタフェースを実現し、Timer内部にはTimerThreadがThreadから継承されている.
一つはThreadクラスを継承しRunnableインタフェースを実現することである
2.Threadクラスの継承とRunnableインタフェースの実現の違い:
3、スレッド実現のすべての方式
3.1.Threadクラスの継承
public class Thread1 extends Thread {
@Override
public void run() {
System.out.println(" Thread ");
}
public static void main(String[] args) {
Thread1 thread = new Thread1();
thread.start();
}
}
3.2、Runnableインタフェースを実現する
public class Thread2 implements Runnable {
@Override
public void run() {
System.out.println(" Runnable ");
}
public static void main(String[] args) {
Runnable runnable = new Thread2();
Thread thread2 = new Thread(runnable);
thread2.start();
}
}
3.3、Callableインタフェースを実現し、FutureTaskで包装する
public class Thread3 implements Callable {
@Override
public String call() throws Exception {
Thread.sleep(5000);
return " Callable , FutureTask , ";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
Thread3 thread3 = new Thread3();
FutureTask futureTask = new FutureTask(thread3);
Thread thread = new Thread(futureTask);
thread.start();
System.out.println(" ");
//
String result = (String) futureTask.get();
System.out.println(result);
}
}
3.4、匿名内部クラス
匿名内部クラスにも様々なバリエーションがあり、これら3つの方法は匿名内部クラスを用いて暗黙的にインスタンス化することができる.
public class Demo{
public static void main(String[] args) throws Exception {
// :Thread
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
}
}.start();
// :Runnable
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}).start();
...
}
}
匿名の内部クラスの利点は、クラスを追加的に定義する必要がなく、コードの可読性が悪いことです.
3.5、Lambda式
public class Demo{
public static void main(String[] args) throws Exception {
new Thread(() -> System.out.println("running") ).start() ;
...
}
}
Runnableは@FunctionalInterface注記で修飾され、インタフェースには1つの方法しかありません.
3.6、スレッドプール
public class DemoThreadTask implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("running");
}
public static void main(String[] args) {
DemoThreadTask task = new DemoThreadTask();
ExecutorService ex = Executors.newCachedThreadPool();
ex.execute(task);
}
}
3.7、タイマー
public class DemoTimmerTask {
public static void main(String[] args) throws Exception {
Timer timer = new Timer();
timer.scheduleAtFixedRate((new TimerTask() {
@Override
public void run() {
System.out.println(" ");
}
}), 2000, 1000);
}
}
TimerTaskはRunnableインタフェースを実現し、Timer内部にはTimerThreadがThreadから継承されている.