再学習のJava並行処理 - 最後にスレッドを作成するには、いくつかの方法があります知って好奇心旺盛GET!

スレッドを作成するには、Oracleの公式ドキュメント

  • Java SE 8 API文档: docs.oracle.com/javase/8/do…

    java.lang.Threadのクラスのドキュメントを参照してください。

    1. このクラスは、Threadのサブクラスとして宣言し、runメソッドをオーバーライドしています。

    官方原话:実行の新しいスレッドを作成するには、2つの方法があります。一つは、のサブクラスであるクラスを宣言することですThreadこのサブクラスは、オーバーライドする必要がありrun、クラスのメソッドをThread

    /**
     * 实现线程的第一个方式 继承Thread
     * @author yiren
     */
    public class MyThread extends Thread {
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " Thread running...");
        }
    
        public static void main(String[] args) throws IOException {
            new MyThread().start();
            System.in.read();
        }
    }
    
    
    
    复制代码
    1. runメソッドを達成し、実装するために、Runnableインタフェース。

    官方原话:スレッドを作成するもう1つの方法は、実装するクラスを宣言することであるRunnableインターフェイス。そのクラスは、実装run方法を。

/**
 * 实现线程的第二个方式 实现Runnable接口
 * @author yiren
 */
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " Runnable running...");
    }

    public static void main(String[] args) throws IOException {
        new Thread(new MyRunnable()).start();
        System.in.read();
    }
}

复制代码

2つの髪の方法の長所と短所

    1. コードの構造を検討するまで、タスクの特定のスレッドの実行方法は、コードを実行することです、コードはビジネスに相当し、それはデカップリングと私たちのスレッドを作成する必要があります。
    2. 相続した場合Thread、あなたは非同期タスクを構築したいたびに、私たちは別のスレッドを確立する必要があります。そして、糸の消費量を作成することは、あなたが使用している場合は、比較的大きいRunnable、我々は大幅にスレッドを作成するために、損失や破壊を減らすことができ、スレッドプール、などのツールをうまく利用して取得することができます。資源保存。
    3. Javaは継承された単一継承であるため、Threadクラスの後、あなたは非常に拡張性を制限し、他のクラスから継承することはできません。
    /* What will be run. */
    private Runnable target;

		public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

		private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }
		
		private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        ......
        
        this.target = target;
        
      	......
    }

		@Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
复制代码
  • 二つの方法の性質(上記のスレッドクラスのソースコードから参照されたいです)

    • 継承は、Thread全体れるrun()方法が上書きされます
    • 達成Runnable最終的に方法がされて呼び出さRunnableruntarget.run()
  • 両方の方法は、それの影響がどうなるかある場合は?

    /**
     * @author yiren
     */
    public class MyThreadAndRunnable {
        public static void main(String[] args) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " runnable running...");
                }
            }
            ) {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " thread running...");
                }
            };
    
            // 这个地方应该是执行重写Thread类的run方法中的逻辑!
            thread.start();
        }
    }
    复制代码
    • もちろん、上記オーバーライドしないと述べたメソッドが呼び出され、それ書き換える一切の呼び出しがない場合は、Threadrun()target.run()target.run()
  • 正確には、一方向だけのスレッドを作成し、それはビルドすることですThread2を超えると言うことですつまり、2つの方法がありますが、スレッド実行ユニットをクラス、および達成。

その他のバージョン:

  • スレッドプールのスレッドを作成します。

    /**
     * wrong 线程池创建
     *
     * @author yiren
     */
    public class ThreadPoolExample {
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i = 0; i < 1000; i++) {
                executorService.submit(() -> {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName());
                });
            }
        }
    }
    
    // Executors中的DefaultThreadFactory 
    static class DefaultThreadFactory implements ThreadFactory {
            private static final AtomicInteger poolNumber = new AtomicInteger(1);
            private final ThreadGroup group;
            private final AtomicInteger threadNumber = new AtomicInteger(1);
            private final String namePrefix;
    
            DefaultThreadFactory() {
                SecurityManager s = System.getSecurityManager();
                group = (s != null) ? s.getThreadGroup() :
                                      Thread.currentThread().getThreadGroup();
                namePrefix = "pool-" +
                              poolNumber.getAndIncrement() +
                             "-thread-";
            }
    
            public Thread newThread(Runnable r) {
                Thread t = new Thread(group, r,
                                      namePrefix + threadNumber.getAndIncrement(),
                                      0);
                if (t.isDaemon())
                    t.setDaemon(false);
                if (t.getPriority() != Thread.NORM_PRIORITY)
                    t.setPriority(Thread.NORM_PRIORITY);
                return t;
            }
        }
    复制代码
    • うちnewThread()、既知の方法、でもスレッドプールは、本質的に、使用されThreadたスレッドを作成します。
  • 呼び出し可能とFutureTaskは、スレッドを作成します

  • UML図は、上記スレッドとRunnableを内側から見た、または実際に達成するために使用します。

  • タイマタイマ

    
    /**
     * @author yiren
     */
    public class TimerExample {
        public static void main(String[] args) {
            Timer timer = new Timer();
            // 每隔1s打印下自己的名字
            timer.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " timer running...");
                }
            }, 1000, 1000);
        }
    }
    复制代码
    • それは実際に、Runnableインタフェースを実装しTimerTaskを、あなたは見ることができTimerTask、この抽象クラス
  • 匿名内部クラス、ラムダ式(本質は同じです)

    /**
     * 匿名内部类
     * @author yiren
     */
    public class AnonymousInnerClassExample {
        public static void main(String[] args) {
            new Thread() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            }.start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            }).start();
    
        }
    }
    
    /**
     * lambda表达式
     * @author yiren
     */
    public class LambdaExample {
        public static void main(String[] args) {
            new Thread(() -> System.out.println(Thread.currentThread().getName())).start();
        }
    }
    复制代码

私について

  • 杭州、通常の学部読み取り、コンピュータ科学と技術的専門知識、20年の卒業をコーディネート。
  • 主にJava開発を行って、Golang、シェルについて書きます。マイクロサービス、ビッグデータはこの方向に行う準備ができ、興味を持って。
  • あなた首長光スプレーは狂った兄が学習され、新人段階に現在あります。
  • メッセージ交換を残すようこそ!

おすすめ

転載: juejin.im/post/5e3f9669e51d4526cb160ee9