📜  实现Runnable的内部类和匿名内部类|并发编程方法 3

📅  最后修改于: 2022-05-13 01:55:07.266000             🧑  作者: Mango

实现Runnable的内部类和匿名内部类|并发编程方法 3

先决条件: Java中并发编程的不同方法

实现 Runnable 的内部类

  1. 在这种方法中,用户将实现 Runnable 的类的类定义物理地放在主类的类定义中。
    public class OuterClass{
        private class InnerClass implements Runnable{
            public void run(){
            }
        }
    }
    
  2. 然后将 run() 方法放入内部类并传递给 execute 方法。执行并不真正意味着执行。这意味着可以执行。例如,如果用户的池大小为 5,并且任务队列中有 10 个任务,则第 6 个任务在前 5 个任务中的一个完成之前不会开始执行。
    taskList.execute(new InnerClass());
    

实际实施:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
  
// Java Program to depict Concurrent
// Programming in action
public class OuterClass {
  
    // Driver method
    public static void main(String[] args)
    {
        new OuterClass().startThreads();
    }
  
    // Starts the threads and calls run method
    // method of the runnable interface
    private void startThreads()
    {
        ExecutorService taskList
            = Executors.newFixedThreadPool(2);
  
        taskList.execute(new InnerClass(1));
        taskList.execute(new InnerClass(2));
        taskList.execute(new InnerClass(3));
        taskList.execute(new InnerClass(4));
        taskList.execute(new InnerClass(5));
        taskList.shutdown();
    }
  
    // Pauses execution allowing time for
    // system to switch back and forth
    private void pause(double seconds)
    {
        try {
            Thread.sleep(Math.round(1000.0 * seconds));
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
  
    // Inner Class
    public class InnerClass implements Runnable {
  
        private int loopLimit;
  
        // Constructor to define
        // different limits
        InnerClass(int loopLimit)
        {
            this.loopLimit = loopLimit;
        }
  
        // Prints thread name and value
        // of the counter variable
        @Override
        public void run()
        {
            for (int i = 0; i < loopLimit; i++) {
                System.out.println(
                    Thread.currentThread().getName()
                    + " Counter: " + i);
                pause(Math.random());
            }
        }
    }
}

输出:

pool-1-thread-1 Counter: 0
pool-1-thread-2 Counter: 0
pool-1-thread-1 Counter: 0
pool-1-thread-2 Counter: 1
pool-1-thread-1 Counter: 1
pool-1-thread-2 Counter: 0
pool-1-thread-2 Counter: 1
pool-1-thread-1 Counter: 2
pool-1-thread-1 Counter: 0
pool-1-thread-2 Counter: 2
pool-1-thread-1 Counter: 1
pool-1-thread-2 Counter: 3
pool-1-thread-1 Counter: 2
pool-1-thread-1 Counter: 3
pool-1-thread-1 Counter: 4

好处:

  1. 访问主应用程序很容易,因为内部类中的方法可以访问外部类的任何公共或私有方法或实例变量。
  2. 与单独的类一样,用户可以将参数传递给将它们存储在运行使用的实例变量中的构造函数。

缺点:

  1. 由于 run 方法与此应用程序密切相关,因此存在紧密耦合的缺点。 run 方法不能在其他地方重用。
  2. 比赛条件存在严重危险。当用户想要访问共享数据(主应用程序中的数据)时,专门使用内部类。

实现 Runnable 的匿名内部类

匿名内部类:内部类在应用程序中使用得如此频繁,以至于开发人员经常希望通过使用匿名内部类来缩短语法,其中用户给出类定义并一举实例化类。由于匿名内部类是内部类,它们具有与内部类相同的优点,但它们更短更简洁。它们的缺点是它们对初学者来说有点混乱,没有构造函数并且它们不能在其他地方重用。

实际实施:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
  
// Concurrent programming using
// Anonymous Inner Class
public class MyClass {
  
    // Driver method
    public static void main(String[] args)
    {
        new MyClass().startThreads();
    }
  
    // Starting threads with pool size as 2
    private void startThreads()
    {
        ExecutorService taskList
            = Executors.newFixedThreadPool(2);
  
        for (int i = 0; i < 5; i++) {
            int finalI = i + 1;
  
            // Giving the class definition
            // and instantiating it all at once
            taskList.execute(new Runnable() {
  
                // Prints thread name and value
                // of the counter variable
                @Override
                public void run()
                {
                    for (int j = 0; j < finalI; j++) {
                        System.out.println(
                            Thread
                                .currentThread()
                                .getName()
                            + " Counter:" + j);
                        pause(Math.random());
                    }
                }
            });
        }
        taskList.shutdown();
    }
  
    // Pauses execution allowing time for
    // system to switch back and forth
    private void pause(double seconds)
    {
        try {
            Thread.sleep(
                Math.round(1000.0 * seconds));
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

输出:

pool-1-thread-1 Counter:0
pool-1-thread-2 Counter:0
pool-1-thread-2 Counter:1
pool-1-thread-1 Counter:0
pool-1-thread-2 Counter:0
pool-1-thread-1 Counter:1
pool-1-thread-2 Counter:1
pool-1-thread-1 Counter:2
pool-1-thread-2 Counter:2
pool-1-thread-2 Counter:3
pool-1-thread-1 Counter:0
pool-1-thread-1 Counter:1
pool-1-thread-1 Counter:2
pool-1-thread-1 Counter:3
pool-1-thread-1 Counter:4