JavaRush /Java Blog /Random EN /Coffee break #112. How to declare, initialize and iterate...

Coffee break #112. How to declare, initialize and iterate over an array in Java. How to stop a Java thread without using Thread.stop()?

Published in the Random EN group

How to declare, initialize and iterate over an array in Java

Source: FreeCodeCamp In this article we will talk about arrays in Java. We'll look at a few examples to help you understand what an array is, how to declare it, and how to use it in Java code. Coffee break #112.  How to declare, initialize and iterate over an array in Java.  How to stop a Java thread without using Thread.stop()?  - 1

What is an array?

In Java, we use an array to store multiple values ​​of the same data type in a single variable. It can also be thought of as a collection of values ​​of the same data type. This means that if you are going to store strings in your array, for example, then all the values ​​in your array must be strings.

How to declare an array in Java

We use square brackets [ ] to declare an array . Like that:
String[] names;
Here we have declared a variable called names which will hold an array of strings. If we need to declare a variable for integers (integers), then we will do it like this:
int[] myIntegers;
So, to create an array, we specify the type of data that will be stored in the array, followed by square brackets and then the name of the array.

How to initialize an array in Java

To initialize an array means to assign values ​​to the array. Let's initialize the arrays we declared in the previous section:
String[] names = {"John", "Jade", "Love", "Allen"};
int[] myIntegers = {10, 11, 12};
We initialized our arrays by passing values ​​of the same data type, separating each value with a comma. If we wanted to access the elements/values ​​in our array, we would access their index number in the array. The index of the first element is 0. Here is an example:
String[] names = {"John", "Jade", "Love", "Allen"};

System.out.println(names[0]);
// John

System.out.println(names[1]);
// Jade

System.out.println(names[2]);
// Love

System.out.println(names[3]);
// Allen
Now that we know how to access each element, let's change the value of the third element.
String[] names = {"John", "Jade", "Love", "Allen"};
names[2] = "Victor";

System.out.println(names[2]);
// Victor
We can also check the length of an array using the length property . Here's an example:
String[] names = {"John", "Jade", "Love", "Allen"};
System.out.println(names.length);
// 4

How to iterate through an array in Java

We can use a for loop to iterate through the elements of an array .
String[] names = {"John", "Jade", "Love", "Allen"};
for (int i = 0; i < names.length; i++) {
  System.out.println(names[i]);
}

// John
// Jade
// Love
// Allen
The loop above will print the elements of our array. We used the length property to specify how many times the loop should run.

Conclusion

In this article, we learned how to declare and initialize arrays in Java code. We also saw how to access each element of an array and how to loop through those elements. Happy coding!

How to stop a Java thread without using Thread.stop()?

Source: 4comprehension If you're reading this, then you're probably wondering why, and most importantly, how to stop a thread if you can't just rely on the Thread#stop() method, which has been deprecated since Java 1.2? Coffee break #112.  How to declare, initialize and iterate over an array in Java.  How to stop a Java thread without using Thread.stop()?  - 2The short answer is that you should use interruptions because Thread#stop is unsafe. But if you want to understand why, how, and what that pesky InterruptedException is for , keep reading.

Problem with Thread#stop()

No matter how intuitive it may sound, interrupting an already running thread, starting and stopping are two completely different cases. Why? When we start a new thread, we are starting from scratch, which is a well-defined state, but when we try to stop an existing thread, it may happen in the middle of an operation that cannot be interrupted immediately . Imagine a thread making changes to a thread-safe data structure. While it is in the middle of the critical section... and then the thread magically disappears - the locks are released, and now another thread can observe the data structure left in an inconsistent state. Consider the following example of a thread-safe counter with some internal state:
class ThreadSafeCounter {

    private volatile int counter = 0;
    private volatile boolean dirty = false;

    public synchronized int incrementAndGet() {
        if (dirty) {
            throw new IllegalStateException("this should never happen");
        }
        dirty = true;
        // ...
        Thread.sleep(5000); // boilerplate not included
        // ...
        counter = counter + 1;
        dirty = false;
        return counter;
    }
}
As you can see, the getAndIncrement() method increments the counter and changes the dirty flag . Locks ensure that every time a thread enters getAndIncrement() the dirty flag is set to false . Now let's create a thread and abruptly stop it:
var threadSafeCounter = new ThreadSafeCounter();

var t1 = new Thread(() -> {
    while (true) {
        threadSafeCounter.incrementAndGet();
    }
});

t1.start();
Thread.sleep(500);
t1.stop();

threadSafeCounter.incrementAndGet();

// Exception in thread "main" java.lang.IllegalStateException: this should never happen
Now the threadSafeCounter instance , despite being implemented correctly, is permanently corrupted due to the thread being abruptly stopped. How to fix it?

Cooperative Thread Interruption

Instead of stopping the thread, we should rely on cooperative thread interruption. Simply put, we must ask the thread to stop itself at the right moment using Thread#interrupt . However, calling Thread#interrupt instead of Thread#stop is not enough. Safe termination of a thread can only be achieved by using a shared thread interrupt, which means that within the thread we need to handle interrupt signals, which come in two types:
  • Boolean interrupted flag

  • InterruptedException

Interruptible Flag Handling

While inside a thread, we can check if it has been interrupted by calling one of the methods:
Thread.currentThread().isInterrupted(); // reads the interrupted flag
Thread.interrupted(); // reads and resets the interrupted flag
Since there is no universal way to handle an interrupt, we need to apply an action that suits our context. In the example from the previous section, the thread increments our counter in an infinite loop. Instead of stopping immediately, we could simply wait for the thread to complete its ascending work and then exit the loop:
var threadSafeCounter = new ThreadSafeCounter();

var t1 = new Thread(() -> {
    while (!Thread.interrupted()) {
        threadSafeCounter.incrementAndGet();
    }
});

t1.start();
Thread.sleep(500);
t1.interrupt();

threadSafeCounter.incrementAndGet();
Now the thread terminates safely at the right time without causing chaos.

Handling InterruptedException

What happens if we try to interrupt a waiting thread? Naturally, we cannot take the interruption flag into account because the thread is busy with a blocking operation. That's why InterruptedException exists . This is not a standard exception, but a different form of interrupt signal that exists solely to handle blocking interrupts! Like Thread#interrupted , it resets the interruption flag . Let's change the example above again and introduce pauses before each increment. Now we need to handle the InterruptedException thrown by Thread#sleep :
var threadSafeCounter = new ThreadSafeCounter();

var t1 = new Thread(() -> {
    while (!Thread.interrupted()) {
        threadSafeCounter.incrementAndGet();
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            break;
        }
    }
});

t1.start();
Thread.sleep(500);
t1.interrupt();

assertThat(threadSafeCounter.incrementAndGet()).isGreaterThan(0);
In our case, it was enough to simply exit the loop. But what if you don't think that a specific method should be responsible for handling interrupts? what if the method signature cannot be changed? In this case, we need to restore the interruption flag and/or repackage the exception, for example:
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    throw new RuntimeException(e);
}

Conclusion:

  • Thread#stop isn't deprecated for no reason - it's actually very insecure.

  • Threads are stopped through interruptions - signals interpreted by the thread itself.

  • InterruptedException is not an ordinary exception - it is Java's built-in way of signaling that a thread has been interrupted.

  • Thread.currentThread().isInterrupted() and Thread.interrupted() are not the same thing. The first one simply reads the interruption flag , and the other resets it afterwards.

  • There is no universal way to handle interrupt signals - “it depends on the circumstances.”

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION