Java Questions 1 - 10   «Prev  Next»

Java Thread Priorities

  1. What is the default priority of a thread?

    Answer:
    A thread gets a default priority, that is the priority of the thread of execution that creates it.

  2. How can you set the priority of a thread?

    Answer:
    Thread t= new Thread( r );
    t.setPriority(8);
    

    Priorities are set using a positive integer, usually between 1 and 10, and the JVM will never change the priority of a thread.


  3. What are 3 (static final variables) that define the range of thread priorities?

    Answer:
    Thread.MIN_PRIORITY(1)
    Thread.NORM_PRIORITY(5)
    Thread.MAX_PRIORITY(10)
    

  4. What is the purpose of the yield() method?

    Answer:
    The yield() method is suppose to make the currently running thread head back to the runnable state to allow other threads of the same priority to get their turn.
    So while yield () might and often does make a running thread give up its slot to another runnable thread of the same priority, there is no guarantee.

  5. Will the the JVM will ever change the priority of a thread?

    Answer:
    No.

  6. What steps can I take to protect data from a "race condition"?

    Answer:
    To protect data from a race condition in Java Threads, it is essential to employ strategies that ensure thread safety and data integrity. A race condition occurs when two or more threads access shared data and attempt to change it simultaneously, leading to unpredictable results and data corruption. Here are the steps you can take to prevent race conditions:
    1. Synchronization: Use the `synchronized` keyword to control access to critical sections of your code. Synchronization ensures that only one thread can execute a block of code that manipulates shared data at any given time. You can synchronize a method or a specific block of code within a method.
    2. Locks: Java provides explicit lock objects in the `java.util.concurrent.locks` package, such as `ReentrantLock`. Locks offer more flexible and sophisticated control over shared data access than synchronization. Acquire a lock before accessing shared data and release it afterward.
    3. Atomic Variables: For simple atomic operations on single variables, use atomic classes from the `java.util.concurrent.atomic` package, such as `AtomicInteger` or `AtomicReference`. These classes provide methods for performing atomic operations without synchronization, making them more efficient in some scenarios.
    4. Thread-Local Variables: If each thread needs its instance of a variable (rather than sharing one instance), use `ThreadLocal` variables. `ThreadLocal` provides thread-local variables, ensuring that each thread has its own, independently initialized copy of the variable.
    5. Immutable Objects: Design your data structures to be immutable. Immutable objects are inherently thread-safe since their state cannot change after they are constructed. If a shared data object does not need to be modified, make it immutable.
    6. Concurrent Collections: Replace standard collections like `HashMap` or `ArrayList` with concurrent collections like `ConcurrentHashMap` or `CopyOnWriteArrayList` from the `java.util.concurrent` package. These collections are designed to handle concurrent access and modifications more efficiently than their standard counterparts.
    7. Avoid Holding Locks During I/O: Ensure that threads do not hold locks while performing I/O operations. Holding locks during I/O can lead to performance bottlenecks and increase the chance of deadlocks.
    8. Minimize Lock Granularity: Keep the scope of locks as narrow as possible. Instead of synchronizing entire methods, only synchronize the critical section that accesses or modifies shared data. This approach reduces contention and improves performance.
    9. Use High-Level Concurrency Utilities: Whenever possible, use high-level concurrency utilities like `Executors`, `Future`, and `CompletionService` from the `java.util.concurrent` package. These utilities abstract away many of the complexities of manual thread management and synchronization.

    By applying these strategies, you can significantly reduce the risk of race conditions in your Java applications, ensuring that your data remains consistent and your applications perform reliably in a concurrent environment.


  7. How do you protect a method so that only one thread at a time can be executing that code?

    Answer:
    You do this with the synchronized keyword.

  8. What happens when we enter a synchronized non-static method?

    Answer:
    We automatically acquire the lock associated with the current instance of the class whose code we are executing.

  9. How can you interpret only one lock per object?

    Answer:
    If one thread has picked up the lock, no other thread can pick up the lock until the first thread releases (or returns) the lock.

  10. What does releasing a lock mean?

    Answer:
    It means the thread holding the lock exits the synchronized method.

SEMrush Software