マルチスレッド
概念:スレッドとは、プロセス内の単一の順次制御フローを指します。プロセス内で複数のスレッドを同時に実行でき、各スレッドは異なるタスクを並行して実行します。
ライフサイクル:
-
新しいステータス:
使用後は、新たなキーワードとスレッドのスレッドオブジェクトを作成するには、クラスまたはそのサブクラスを、スレッドオブジェクトは、新しく作成された状態になっています。プログラムがこのスレッドを開始するまで、この状態を維持します。
-
準備完了状態:
スレッドオブジェクトがstart()メソッドを呼び出すと、スレッドは準備完了状態になります。作動可能状態のスレッドは作動可能キューにあり、JVM内のスレッド・スケジューラーのスケジューリングを待ちます。
-
稼働状況:
準備完了状態のスレッドがCPUリソースを獲得すると、そのスレッドはrun()を実行でき、スレッドは実行状態になります。実行状態のスレッドは最も複雑で、ブロックされ、準備ができて、停止する可能性があります。
-
ブロック状態:
スレッドがスリープ(sleep)、suspend(suspend)、およびその他のメソッドを実行する場合、占有されたリソースを失った後、スレッドは実行状態からブロッキング状態に入ります。スリープタイムが経過した後、またはデバイスリソースが取得された後に、準備完了状態に再び入ることができます。それは3つのタイプに分けることができます:
- ブロッキング待ち:実行状態のスレッドは、wait()メソッドを実行して、スレッドをブロッキング待ち状態に移行させます。
- 同期ブロッキング:スレッドは同期同期ロックの取得に失敗します(同期ロックが他のスレッドによって占有されているため)。
- その他のブロッキング:スレッドのsleep()またはjoin()を呼び出してI / O要求が発行されると、スレッドはブロッキング状態になります。sleep()状態がタイムアウトになると、join()はスレッドの終了またはタイムアウトを待機するか、I / O処理が完了すると、スレッドは再び準備完了状態になります。
-
死亡状況:
実行状態のスレッドがタスクを完了するか、他の終了条件が発生すると、スレッドは終了状態に切り替わります。
スレッドの優先度:
値の範囲は1(Thread.MIN_PRIORITY)-10(Thread.MAX_PRIORITY)です。
デフォルトでは、各スレッドには優先度NORM_PRIORITY(5)が割り当てられています。
スレッドの作成:
- Runnableインターフェースを実装することにより、
- Threadクラス自体を継承する。
- CallableおよびFutureを介してスレッドを作成します。
1. Runnableインターフェースを実装する
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
RunnableDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// 让线程睡眠一会
Thread.sleep(50);
}
}catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1.start();
RunnableDemo R2 = new RunnableDemo( "Thread-2");
R2.start();
}
}
演算結果:
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
2.スレッドを継承してスレッドを作成する
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// 让线程睡眠一会
Thread.sleep(50);
}
}catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();
ThreadDemo T2 = new ThreadDemo( "Thread-2");
T2.start();
}
}
演算結果:
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
スレッド方式
次の表は、Threadクラスのいくつかの重要なメソッドを示しています。
シリアルナンバー | メソッドの説明 |
---|---|
1 | public void start()はスレッドの実行を開始し、Java仮想マシンはスレッドのrunメソッドを呼び出します。 |
2 | public void run()スレッドが独立したRunnableオブジェクトを使用して構築されている場合は、Runnableオブジェクトのrunメソッドを呼び出します。それ以外の場合、メソッドは何もせずに戻ります。 |
3 | public final void setName(String name)は、スレッド名を変更して、パラメーター名と同じにします。 |
4 | public final void setPriority(int priority)は、スレッドの優先度を変更します。 |
5 | public final void setDaemon(boolean on)は、スレッドをデーモンスレッドまたはユーザースレッドとしてマークします。 |
6 | public final void join(long millisec)は、このスレッドの終了を最大でmillisミリ秒待機します。 |
7 | public void interrupt()はスレッドに割り込みます。 |
8 | public final boolean isAlive()スレッドが生きているかどうかをテストします。 |
スレッドがアクティブかどうかをテストします。上記のメソッドは、Threadオブジェクトによって呼び出されます。次のメソッドは、Threadクラスの静的メソッドです。
シリアルナンバー | メソッドの説明 |
---|---|
1 | public static void yield()現在実行中のスレッドオブジェクトを一時停止し、他のスレッドを実行します。 |
2 | public static void sleep(long millisec)現在実行中のスレッドを、指定されたミリ秒数以内にスリープ(実行を中断)しますこの操作は、システムタイマーとスケジューラの精度と精度の影響を受けます。 |
3 | public static boolean holdLock(Object x)は、現在のスレッドが指定されたオブジェクトのモニターロックを保持している場合にのみtrueを返します。 |
4 | public static Thread currentThread()は、現在実行中のスレッドオブジェクトへの参照を返します。 |
5 | public static void dumpStack()は、現在のスレッドのスタックトレースを標準エラーストリームに出力します。 |
CallableおよびFutureを介してスレッドを作成します。
- \ 1。Callableインターフェースの実装クラスを作成し、call()メソッドを実装します。call()メソッドはスレッド実行本体になり、戻り値を持ちます。
- \ 2。Callable実装クラスのインスタンスを作成し、FutureTaskクラスを使用してCallableオブジェクトをラップします。FutureTaskオブジェクトは、Callableオブジェクトのcall()メソッドの戻り値をカプセル化します。
- \ 3。ThreadオブジェクトのターゲットとしてFutureTaskオブジェクトを使用して、新しいスレッドを作成および開始します。
- \ 4。子スレッドの実行が終了した後、FutureTaskオブジェクトのget()メソッドを呼び出して戻り値を取得します。
public class CallableThreadTest implements Callable<Integer> {
public static void main(String[] args)
{
CallableThreadTest ctt = new CallableThreadTest();
FutureTask<Integer> ft = new FutureTask<>(ctt);
for(int i = 0;i < 100;i++)
{
System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i);
if(i==20)
{
new Thread(ft,"有返回值的线程").start();
}
}
try
{
System.out.println("子线程的返回值:"+ft.get());
} catch (InterruptedException e)
{
e.printStackTrace();
} catch (ExecutionException e)
{
e.printStackTrace();
}
}
@Override
public Integer call() throws Exception
{
int i = 0;
for(;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+" "+i);
}
return i;
}
}
匿名の内部クラスを使用してスレッドを作成します。
/*
* 匿名内部类的格式:
*/
public class ThreadDemo {
public static void main(String[] args) {
// 继承thread类实现多线程
new Thread() {
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(Thread.currentThread().getName() + "--"
+ x);
}
}
}.start();
;
// 实现runnable借口,创建多线程并启动
new Thread(new Runnable() {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(Thread.currentThread().getName() + "--"
+ x);
}
}
}) {
}.start();
// 更有难度的,在Thread匿名内部类的里面再一次重写run方法
//在实际运行时的结果是 hello+x。以thread的run方法为准。但是此处无意义
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int x = 0; x < 100; x++) {
System.out.println("java" + "--" + x);
}
}
}) {
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println("hello" + "--" + x);
}
}
}.start();
}
}
*免責事項:このブログ投稿は私の学習ノートです。新人チュートリアルやその他のネットワークリソースを参照してください。侵害されている場合は、プライベートメッセージを送信してください。*