Java: Есть ли способ создать объект, но он постоянно выполняет свой собственный код? - PullRequest
1 голос
/ 25 апреля 2020

Я довольно новичок в Java, и я не могу на всю жизнь узнать, как это сделать.

public class Main {

    public static void main(String[] args) {
        Test test1 = new Test(2);
        Test test2 = new Test(3);
    }
}

class Test {
    int i;

    public Test(int i) {
        this.i = i;
    }
    // Constantly print out i
}

В принципе, просто для этого я пытаюсь сделать урок постоянно выводить свою собственную переменную i. Я знаю, что есть способ сделать это, создав метод getter и поместив объекты в ArrayList, но я делаю плагин для Minecraft, который требует этот конкретный случай c. Спасибо!

Ответы [ 2 ]

2 голосов
/ 25 апреля 2020

Executors Framework

Как сказано в Ответе kofemann , используйте threads для запуска кода в фоновом режиме. Но обработка потоков напрямую - сложное дело. Таким образом, платформа Executors была добавлена ​​к Java, чтобы упростить эту работу.

В частности, вы хотите, чтобы ScheduledExecutorService выполнял какую-то задачу снова и снова , Используйте класс Executors, чтобы получить экземпляр ScheduledExecutorService, поддерживаемый пулом из одного или нескольких потоков. Дайте этой задаче объект Runnable, метод run которого выполняет желаемую задачу. Укажите начальную задержку или ноль, чтобы начать немедленно. И укажите период, количество времени, которое должно пройти перед повторным выполнением задачи.

Важно: обязательно завершите работу службы исполнителя, когда она вам больше не нужна или когда ваше приложение закрывается. В противном случае потоки могут продолжать работать бесконечно.

Вот класс Count для хранения нашего целого числа.

package work.basil.example;

public class Count
{
    private int count;

    public Count ( int count )
    {
        this.count = count;
    }

    public int getCount ( ) { return this.count; }
}

А вот пример кода. Мы определяем работоспособный объект, настраиваем службу исполнителя, запускаем ее, ждем некоторое время, затем выключаем службу исполнителя.

Count count = new Count( 42 );

Runnable runnable = ( ) -> {
    int i = count.getCount();
    System.out.println( "Count is currently: " + i + " at " + ZonedDateTime.now() );
};

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
long delay = 0;
long period = 5;
ses.scheduleAtFixedRate( runnable , delay , period , TimeUnit.SECONDS );

// … eventually shutdown your executor service and its backing thread pool.
try
{
    Thread.sleep( TimeUnit.MINUTES.toMillis( 1 ) );
}
catch ( InterruptedException e )
{
    e.printStackTrace();
}
ses.shutdown();
System.out.println( "Done running example of scheduled executor service." );

При запуске.

Количество в настоящее время: 42 в 2020-04-25T13: 08: 14.484127-07: 00 [America / Los_Angeles]

Счет в настоящее время: 42 в 2020-04-25T13: 08: 19.465306-07: 00 [America / Los_Angeles]

В настоящее время счетчик: 42 в 2020-04-25T13: 09: 14.460006-07: 00 [America / Los_Angeles]

Выполнен пример запуска службы запланированного исполнителя.

Совместное использование ресурсов между потоками, в данном случае экземпляр Count и содержащаяся в нем переменная int несут сложности. Изучите превосходную книгу Java Параллелизм на практике Брайана Гетца и др.

Я предполагаю, что вы намереваетесь увеличить этот счет во время выполнения вашего приложения , Если это так, мы должны защитить доступ к счетчику, потому что один поток может изменять число, в то время как другой читает его.

Java предоставляет класс AtomicInteger для этой цели. Измените примитив int в нашем классе Count, чтобы использовать вместо него объект AtomicInteger. Мы добавили метод increment, чтобы увеличить значение этого AtomicInteger. И мы используем поточно-безопасный метод AtomicInteger::get для получения его значения.

package work.basil.example;

import java.util.concurrent.atomic.AtomicInteger;

public class Count
{
    private AtomicInteger count;

    public Count ( int count )
    {
        this.count = new AtomicInteger( count );
    }

    public int getCount ( ) { return this.count.get(); }

    public int increment ( ) { return this.count.incrementAndGet(); }
}

Нам не нужно вносить какие-либо изменения в наш код, который использует класс Count.

Если вы хотите увидеть увеличение действия, настройте еще одну задачу Runnable. Запланируйте эту задачу на службе исполнителя, а также на других наших Runnable.

Count count = new Count( 42 );

Runnable runnable = ( ) -> {
    int i = count.getCount();
    System.out.println( "Count is currently: " + i + " at " + ZonedDateTime.now() );
};

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
long delay = 0;
long period = 5;
ses.scheduleAtFixedRate( runnable , delay , period , TimeUnit.SECONDS );

Runnable runnableIncrementor = ( ) -> {
    int i = count.increment();
    System.out.println( "Incrementing count: " + i + " at " + ZonedDateTime.now() );
};
ses.scheduleAtFixedRate( runnableIncrementor , 7 , 13 , TimeUnit.SECONDS );

// … eventually shutdown your executor service and its backing thread pool.
try
{
    Thread.sleep( TimeUnit.MINUTES.toMillis( 1 ) );
}
catch ( InterruptedException e )
{
    e.printStackTrace();
}
ses.shutdown();
System.out.println( "Done running example of scheduled executor service." );

При запуске.

Счет в настоящее время: 42 в 2020-04-25T13: 26: 14.405538-07: 00 [America / Los_Angeles]

Счет в настоящее время: 42 в 2020-04-25T13: 26: 19.372358-07: 00 [America / Los_Angeles]

Увеличение счетчика: 43 в 2020-04-25T13: 26: 21.379639-07: 00 [ Америка / Лос-Анджелес]

Количество в настоящее время: 43 в 2020-04-25T13: 26: 24.371442-07: 00 [Америка / Лос-Анджелес]

1 голос
/ 25 апреля 2020

Это для java потоков . Вот пример.

public class Main {

    public static void main(String[] args) {
        new Test(2).start();
        new Test(3).start();

        // some code to wait for thread completion 
    }
}

class Test extends Thread {
    int i;

    public Test(int i) {
        this.i = i;
    }

    @Override
    public void run() {
        while(true) {
            // Constantly print out i
        }
    }
}

Ну, есть гораздо лучшие способы сделать это, но вы поняли.

...