Since I read "Design Patterns Learned in Java Language (Multithread Edition)", I will record the main points.
--Method 1 Use the java.lang.Thread class.
The behavior of the newly started thread is described in the ** run ** method of the ** Thread ** class. Calling the ** start ** method of the Thread class starts a new thread. When you call the start method, a new thread is started and the run method is called.
public class Main {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
for (int i = 0; i < 100; i++) {
System.out.print("1");
}
}
public static class MyThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("2");
}
}
}
}
First time
Execution result
11111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211111111111111111111111111111111111111111111111111111111111111111111222222
Second time
Execution result
11111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
--Method 2 Use the Runnbale interface
Start a thread using an instance of a class that implements the ** Runnable ** interface. The Runnable interface is declared as follows:
public interface Runnable {
public abstract void run();
}
Create a class that implements the Runnbale interface, pass the instance to the Thread constructor, and call the start method.
public class Main {
public static void main(String[] args) {
Runnable myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
for (int i = 0; i < 100; i++) {
System.out.print("1");
}
}
public static class MyThread implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("2");
}
}
}
}
Use Thread.sleep. Enclose the ** sleep ** method call in try-catch. The sleep method throws a ** InterruptedException ** exception.
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.print("1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
The disappointing thread behavior caused by the competition (race) between thread A and thread B is called ** data race **. Traffic control is required to prevent data trace, which is generally called ** exclusive control **. In Java, the keyword ** synchronized ** is used when exclusive control of threads is performed. If you declare a method with the keyword synchronized, the method will run in a single thread. Such methods are called ** synchronized methods ** and ** synchronized methods **.
public class Bank {
private int money;
private String name;
public Bank(String name, int money) {
this.name = name;
this.money = money;
}
//Deposit
public synchronized void deposit(int m) { //Synchronous method
money += m;
}
//Pull out
public synchronized boolean withdraw(int m) { //Synchronous method
if (money >= m) {
money -= m;
return true;
} else {
return false;
}
}
public String getName() {
return name;
}
}
If even one thread has a ** lock **, no other thread can enter. The lock is ** released ** when the thread that was executing the synchronized method finishes executing that method. When the lock is released, any one of the threads that was previously locked and could not be entered can take the lock.
Locks exist for each instance. Executing the synchronized method of one instance does not mean that the synchronized method of another instance cannot be executed.
You can check if the current thread has a lock on an object with the Thread.holdsLock method.
Use the ** synchronized block ** if you want some of the methods to work in a single thread instead of the entire method.
synchronized (formula) {
...
}
The following are equivalent
synchronized void method() {
...
}
void method() {
synchronized (this) {
...
}
}
The following are equivalent
class Something {
static synchronized void method() {
....
}
}
class Something {
static void method() {
synchronized (Something.class) {
....
}
}
}
Every instance has a ** weight set **. A waitset is a set of threads that execute the ** wait ** method of that instance and are stopped. It's like a thread waiting room for each instance. When the thread executes the wait method, it pauses its operation and enters a waiting room called a wait set. The thread waits in its weight set until one of the following occurs:
--Worn by the notify method from another thread --Worn by the notifyAll method from another thread --Worn by interrupt method from another thread --wait method times out
For example obj.wait(); When the statement is executed, the current thread is suspended and the wait set of instance obj is entered. This is said that the thread is waiting on obj. The thread must have a lock in order to execute the wait method.
Weight set is a virtual concept. There is no method to get a list of threads weighted on an instance.
(There is an easy-to-understand diagram of this concept in this book, so please refer to it.)
Use the ** notify ** method to remove one of the threads in the weight set from the weight set. For example obj.notify(); Is executed by a thread. Then, one thread is selected from the threads in the obj weight set, and that thread is woken up. The awakened thread goes out of the weight set. The thread must have a lock in order to execute the notify method. ** Threads spawned by notify do not resume execution the moment they notify. ** Because the thread that notified has the lock at the moment of notifying. ** When executing the notify method, if there are multiple threads waiting in the wait set, which thread is selected is not specified in the specifications. ** **
Use the notifyAll method to bring all threads in the weight set out of the weight set. Like the wait method and norify method, the notifyAll method can only be called from the thread that has the lock of the instance to be called. Like notify, the thread that came out is not restarted immediately. After the thread that executed notifyAll releases the lock, only one lucky thread can resume execution.
An exception ** java.lang.IllegalMonitorStateException ** is thrown when a thread that does not have a lock calls wait, notify, notifyAll.
The thread has the following states.
--NEW: State of threads that are not started --RUNNABLE: State of threads running in the Java virtual machine --TERMINATED: State of terminated thread --WAITING: The state of a thread waiting indefinitely for another thread to perform a particular action. --TIMED_WAITING: The state of the thread waiting for another thread to perform the action for the specified wait time. --BLOCKED: The state of the thread that is blocked and waiting for the monitor lock.
These states can be obtained with the getState method of the Thread class.
The source code can be downloaded from the author's HP. http://www.hyuki.com
Recommended Posts