GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing zetcode.com — Java Thread - working with threads in Java Java Threadlast modified July 13, 2024 In this article we introduce Java threads and list their advantages and disadvantages. We mention what kind of issues arise when working with threads. We show how to create simple threads in a few examples. A Java thread is a lightweight unit of execution within a program. It allows a program to perform multiple tasks apparently concurrently. The Java virtual machine allows an application to have multiple threads of execution running concurrently. Every Java program has at least one thread, known as the main thread. The Java Virtual Machine creates this thread when the program starts, invoking the main method. The benefits of using Java threads are:
Common use cases for Java threads are:
Since threads run concurrently, the order of code execution is unpredictable. When threads read and write the same variables, it can lead to concurrency problems. To avoid this, share as few attributes between threads as possible and use synchronization techniques. Multithreading issuesMultithreaded programs are inherently more complex than single-threaded ones. This can lead to bugs that are hard to identify and reproduce. Common concurrency issues include:
SynchronizationThread synchronization is the capability to control access to shared resources by multiple threads. It ensures that only one thread can access a critical section of code or a shared resource at a time. Synchronization techniques include:
Note that ensuring thread safety by synchronizing access to shared resources can introduce overhead. This can slow down our program compared to a single-threaded approach. Creating threads
There are two main ways to create threads in Java: a) extending a
Main.java
class Worker implements Runnable {
@Override
public void run() {
System.out.println("worker is running");
}
}
void main() {
System.out.println("main thread started");
var myRunnable = new Worker();
var thread = new Thread(myRunnable);
thread.start();
System.out.println("main thread ended");
}
Here we create a
In the second example, the Main.java
class Worker extends Thread {
@Override
public void run() {
System.out.println("worker is running");
}
}
void main() {
System.out.println("main thread started");
var myRunnable = new Worker();
var thread = new Thread(myRunnable);
thread.start();
System.out.println("main thread ended");
}
In the example we extend from the Thread.sleep
The Main.java
class Task implements Runnable {
private int delay;
private String name;
public Task(String name, int delay) {
this.name = name;
this.delay = delay;
}
@Override
public void run() {
try {
System.out.printf("starting task %s%n", this.name);
Thread.sleep(delay);
System.out.printf("finishing task %s%n", this.name);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void main() {
var task1 = new Task("Task 2000", 2000);
var t1 = new Thread(task1);
t1.start();
var task2 = new Task("Task 1000", 1000);
var t2 = new Thread(task2);
t2.start();
var task3 = new Task("Task 500", 500);
var t3 = new Thread(task3);
t3.start();
System.out.println("tasks launched");
}
The $ java Main.java tasks launched starting task Task 1000 starting task Task 2000 starting task Task 500 finishing task Task 500 finishing task Task 1000 finishing task Task 2000 First, the main program thread finishes. The three threads start in unpredictable order. They finish later depending on their sleep value. Thread join method
The Use cases of the method:
Main.java
class Worker extends Thread {
private int delay;
private String msg;
public Worker(int delay, String msg) {
this.delay = delay;
this.msg = msg;
}
public void run() {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(msg);
}
}
void main() {
var w1 = new Worker(2000, "Hello there");
var w2 = new Worker(1000, "New mail received");
var w3 = new Worker(500, "Notes taken");
// start three threads
w1.start();
w2.start();
w3.start();
// wait for threads to end
try {
// join is a blocker method which waits for a thread to complete.
// the w1.join() causes the current (main) thread to pause execution
// until w1's thread terminates.
w1.join();
w2.join();
w3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("finished tasks");
}
In the program, we start three additional threads. Using $ java Main.java Notes taken New mail received Hello there finished tasks The finished tasks appears after the three threads end their tasks. SwingWorkerSwingWorker is designed specifically to run long-running tasks in a separate thread away from the Swing Event Dispatch Thread (EDT). It simplifies performing long-running tasks in the background while keeping the EDT responsive.
The long-running task is placed in the com/zetcode/ButtonTaskEx.java
package com.zetcode;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import java.awt.EventQueue;
class MyWorker extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() throws Exception {
// Simulate a time-consuming task
Thread.sleep(3000);
return null;
}
@Override
protected void done() {
System.out.println("task done");
}
}
public class ButtonTaskEx extends JFrame {
public ButtonTaskEx() {
initUI();
}
private void initUI() {
var taskButton = new JButton("Task");
taskButton.addActionListener((event) -> {
var worker = new MyWorker();
worker.execute();
});
// taskButton.addActionListener((event) -> {
// try {
// Thread.sleep(3000);
// System.out.println("task done");
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// });
createLayout(taskButton);
setTitle("Task button");
setSize(500, 450);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void createLayout(JComponent... arg) {
var pane = getContentPane();
var gl = new GroupLayout(pane);
pane.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
gl.setHorizontalGroup(gl.createSequentialGroup()
.addComponent(arg[0])
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addComponent(arg[0])
);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
var ex = new ButtonTaskEx();
ex.setVisible(true);
});
}
}
In the program we have a button that starts a 3s background task. If we place
the task in the SourceIn this article we defined Java threads and provided some basic code examples. AuthorMy name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming. List all Java tutorials. |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |