マルチスレッド関連の問題
1.プロセスとは何ですか?
プログラムが実行されています
2.スレッドとは何ですか?
経路独立した機能の実装を完了するためのプロセスのサブユニット、
3.なぜあなたは、複数のスレッドを開くために必要なのですか?
- 特定のタスクを実行するために時間のかかる操作は、スレッドのブロッキングを防ぐために、複数のスレッドを開くために必要がある場合
- あなたは、同時に2つのタスクが実行中のように見せることができ
- CPU使用量が増加し、プロセスとメモリ使用量を改善するために、
4.なぜ複数のスレッドが同時に実行開くことができますか?
CPUの実行の高速スイッチング速度は、肉眼では、ギャップすることはできませんので
5.効率の向上や効率性を減らすために、マルチスレッド処理が可能ではないターン?
いいえ、複数のスレッド、遅く効率が、CPUリソースの無駄が少なく、そのCPUの使用の合理化
6.平行と同時の差
- 同時実行 - 同時に複数のスレッドの>同時実行は、同時に実行のように見えます
- パラレル - >同時に実行する複数のスレッドを実行する(時間の単位に分割することができない)同じ時間スケールで本質的です
特定の最小時間スケール単位でCPUは、ステートメントの実行は、プロセスのスレッドのアトミック細分ありません
スレッドには、道を開きます
Javaはスレッドを作成するために、3つのメソッドを提供します。
1. Threadクラスは、道を継承します
2. Runnableをする方法を達成するために
3.呼び出し可能と未来を通じてスレッドを作成します。
方法1:Threadクラスの継承
1.カスタムクラスは、Threadクラスを継承しMyThread。3つの
2.MyThreadクラスオーバーライドrun()メソッド。
3.スレッドオブジェクトを作成します。
4.スレッドを起動します。
注:
1、start()メソッドの代わりにランの()メソッド使用して、スレッドを開始する
2を、複数のスレッドを開始できませんThreadオブジェクトとrunメソッドを呼び出すには、startメソッドの違いを呼び出しますか?
- Threadオブジェクトは、runメソッドが開いたスレッドではありません呼び出します。唯一のオブジェクトのメソッド呼び出し。
- オープンスレッドオブジェクトは、スレッドを呼び出しを開始し、JVMが開いたスレッドで実行のrunメソッドを呼び出してみましょう
コードは、開いているスレッドを使用して実証します
// 方式二:实现Runnable接口
class CalculateRunnable implements Runnable {
private int m;
private int n;
public CalculateRunnable(int m, int n) {
super();
this.m = m;
this.n = n;
}
public CalculateRunnable() {
super();
}
@Override
public void run() {
int sum = 0;
for (int i = m; i <= n; i++) {
sum += i;
System.out.println("CalculateRunnable子线程: " + i);
}
System.out.println(m + "~" + n + "的和: " + sum);
}
}
第二の方法:Runnableを実装
1.カスタムクラスはRunnableを実装MyRunnable
2オーバーライドrun()メソッド
3 MyRunnableは、オブジェクト・クラスの作成
4.スレッドクラスのオブジェクトを作成し、オブジェクトが通過する設定パラメータとして、ステップ3で作成されている
5。スレッドを開始インターフェイスメソッドを実装することの利点は、
Javaの単一継承の制限をもたらし避けることができます。
同じプログラムコードの複数の同一の資源、プログラムのコードを持つスレッドが、データ有効な分離は、好ましくは、オブジェクト指向設計を反映するケースを扱うようになっています。コードは、次の2つの方法のオープンスレッドを示しています
// 方式一:继承Thread类
class CopyThread extends Thread {
private File srcFile;
private File descFile;
public CopyThread() {
super();
}
public CopyThread(File srcFile, File descFile) {
super();
this.srcFile = srcFile;
this.descFile = descFile;
}
@Override
public void run() {
// main方法怎么写,这里就怎么写
copy(srcFile, descFile);
}
public void copy(File srcFile, File descFile) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(descFile))){
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Mainメソッドの呼び出し
public static void main(String[] args) {
CopyThread ct = new CopyThread(new File("Test.java"), new File("Test.txt"));
CalculateRunnable cr = new CalculateRunnable(1, 200);
Thread t = new Thread(cr);
ct.start();
t.start();
for (int i = 0; i < 100; i++) {
System.out.println("main线程: " + i);
}
}
三つの方法:呼び出し可能と未来は、スレッドを作成します。
- 呼び出し可能インターフェースの実装クラスを作成し、実行、および戻り値のスレッドとして()メソッドの呼び出し、呼び出し()メソッドを実装します。
- 呼び出し可能な値を返す()メソッドの呼び出しのFutureTask呼び出し可能オブジェクトをカプセル化するオブジェクト呼び出し可能FutureTaskクラスオブジェクトを、包装用いて、実装クラスのインスタンスを作成します。
- 作成し、新しいスレッドを開始するために、ターゲットオブジェクトとしてFutureTaskスレッドオブジェクトを使用します。
- サブスレッドの実行が終了した後、戻り値を取得するFutureTaskオブジェクトのget()メソッドを呼び出します。
Runnableを継承し、機能の仕方を達成スレッド:
1.は結果を返しません。
2.異常な
呼び出し可能とRunnableを差異:
1.Runnable戻り値なし、スローされた例外なく
2.Callableは、リターンスタートスレッドで値を取得し、異常な子スレッドを受け入れることができます
スレッド間のデータ転送:スレッド間通信
スレッドは、スレッドBをオープンしました
- コンストラクタ経由> B
B - >呼び出し可能な方法によってA
public class CallableDemo{
public static void main(String[] args) {
FutureTask<Integer> task = new FutureTask<>(new CalculateCallable(0,100));
Thread t = new Thread(task);
t.start();
try {
Integer i = task.get();
System.out.println("计算结果: " + i);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("程序结束");
}
}
class CalculateCallable implements Callable<Integer> {
private int m;
private int n;
public CalculateCallable() {
super();
}
public CalculateCallable(int m, int n) {
super();
this.m = m;
this.n = n;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = m; i <= n; i++) {
System.out.println("子线程: " + i);
sum += i;
throw new NullPointerException("空指针异常!");
}
return sum;
}
}