匿名内部クラスを使用してJavaでスレッドを開始する実装方法、スレッドプール、およびタイマー


序文

この記事では、最初にスレッドに存在する5つの状態を明確にし、次に以前に学習した匿名内部クラスの知識を使用してスレッドを実装し、次にマルチスレッドでのスレッドプールの概念を紹介し、で3つのスレッドプール実装メソッドを紹介します。最後に、マルチスレッドでのタイマーの概念を理解し、2つのコードを組み合わせて、タイマーの使用方法を示します。

1つは、スレッドの状態です。

  • 5つの州
  1. 新規:スレッドが作成されます
  2. 準備完了:CPUの実行資格はありますが、CPUの実行権はありません。
  3. 操作:CPUの実行資格とCPUの実行権があります
  4. ブロッキング:CPUの実行資格もCPUの実行権もありません
  5. :CPUの実行資格もCPUの実行権もありません
  • スレッドの実行状態図
    ここに画像の説明を挿入

2つ目は、匿名の内部クラスを使用してスレッドを開始する

1.実施方法1

  • 基本コード
 new Thread(){
    
    
            @Override
            public void run() {
    
    
                System.out.println("线程1执行了");
            }
        }.start();
  • パラメータ化された構造を呼び出して名前を渡します
new Thread("线程2"){
    
    
            @Override
            public void run() {
    
    
                System.out.println(Thread.currentThread().getName()+"执行了");
            }
        }.start();

2.実装2

  • 基本コード
new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("线程3执行了");
            }
        }).start();
  • パラメータ化された構造を呼び出して名前を渡します
new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(Thread.currentThread().getName()+"执行了");
            }
        },"线程4").start();

3つ目は、スレッドプールの概念と実装です。

1.スレッドプールの概念

  • プログラムはオペレーティングシステムと対話するように設計されているため、新しいスレッドを開始するためのプログラムのコストは比較的高くなります。また、スレッドプールを使用すると、パフォーマンスが向上します。特に、存続期間の短いスレッドを多数作成するプログラムでは、スレッドプールの使用を検討する必要があります
  • スレッドプールは、実際には、特定の数のスレッドオブジェクトを作成するのに役立つコンテナです。
  • スレッドプール内の各スレッドのコードが終了した後、スレッドは停止しませんが、アイドル状態と呼ばれるスレッドプールに戻り、次のオブジェクトが使用するのを待ちます

2.スレッドプールを実装する3つの方法

  • JDK5より前は、独自のスレッドプールを手動で実装する必要がありました。JDK5以降、Javaにはスレッドプールのサポートが組み込まれています。
  • JDK5は、スレッドプールを生成するために新しいExecutorsファクトリクラス追加しました。次のようないくつかのメソッドがあります。
1.スレッドプールの実装方法1
  • public static ExecutorService newCachedThreadPool()
    は、タスクの数に応じて、スレッドに対応するスレッドの数を作成します(タスク数=スレッド数)
  • コード:
public class 线程池实现方式1 {
    
    
    public static void main(String[] args) {
    
    
        //通过工厂类,获取线程池对象
        ExecutorService executorService = Executors.newCachedThreadPool();
        //给线程池中提交任务(根据任务数量,创建线程个数)
        //创建了3个线程完成3个任务
        executorService.submit(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                for (int i = 0; i < 1000; i++) {
    
    
                    System.out.println(Thread.currentThread().getName() +"执行任务1");
                }

            }
        });

        executorService.submit(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                for (int i = 0; i < 1000; i++) {
    
    
                    System.out.println(Thread.currentThread().getName()+"执行任务2");
                }

            }
        });

        executorService.submit(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                for (int i = 0; i < 1000; i++) {
    
    
                    System.out.println(Thread.currentThread().getName() + "执行任务3");
                }

            }
        });
        //关闭线程池
        executorService.shutdown();

    }

}
2.スレッドプール実装モード2
  • public static ExecutorService newFixedThreadPool(int nThreads)
    は、指定された数のスレッドを固定的に初期化します(スレッド数は任意に指定します)
  • コード
public class 线程池的实现方式2 {
    
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        //固定初始化3个线程
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        //可以传递callable任务,可以获得线程执行完后的结果
        Future<Integer> future =executorService.submit(new Callable<Integer>() {
    
    
            @Override
            public Integer call() throws Exception {
    
    
                System.out.println("线程执行了");
                return 100;
            }
        });
        //获取线程执行结果的返回值
        Integer integer = future.get();
        System.out.println(integer);

    }
}
3.スレッドプールの実装モード3
  • public static ExecutorService newSingleThreadExecutor()
    はスレッドプールを初期化します(スレッド数は1)
  • コード:
public class 线程池的实现方式3 {
    
    
    public static void main(String[] args) {
    
    
        //初始化一个线程的线程池
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(Thread.currentThread().getName()+"执行了任务1");
            }
        });
        executorService.submit(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(Thread.currentThread().getName() + "执行了任务2");
            }
        });
        executorService.submit(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(Thread.currentThread().getName() + "执行了任务3");
            }
        });
        //注意:该三个任务都是由一个线程完成的

    }
}

第四に、タイマー

  • タイマーは非常に広く使用されているスレッドツールであり、バックグラウンドで実行する複数の時間指定タスクをスケジュールするために使用できます。

  • Javaでは、次を使用できます タイムクラスTimeTaskクラス スケジューリングを定義する機能を実現するため。

  • タイマー:

    • public Timer()
    • public void schedule(TimerTask task、long delay):
    • public void schedule(TimerTask task、long delay、long period);
    • public void schedule(TimerTask task、Date time):
    • public void schedule(TimerTask task、Date firstTime、long period):
  • TimerTask:タイミングタスク

    • public abstract void run()
    • public boolean cancel()

コード例1:

public class 定时器 {
    
    
    public static void main(String[] args) {
    
    
        //timer类,是一种工具,线程用其安排以后在后台线程中执行的任务,可以安排任务执行一次,或者定期重复执行。
        Timer t1 = new Timer();
        //等待多少毫秒之后,执行定时任务
        TimerTask task=new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("爆炸");
            }
        };
        //任务等待5秒执行,1秒不间断执行一次
        t1.schedule(task,1000*5,1000);
        //取消定时器
        //t1.cancel();
        //取消任务
        //task.cancel();
    }
}

コード例2:

public class 定时器2 {
    
    
    public static void main(String[] args) throws ParseException {
    
    
        Timer timer = new Timer();
        String dateStr="2021-01-23 13:00:00";
        Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
        //使用匿名内部类创建TimeTask
        timer.schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("从今日起,每日13:00疫情填报");
            }
        },date,1000*60*60*24);

    }
}

おすすめ

転載: blog.csdn.net/m0_46988935/article/details/112986266