This article has been published exclusively by guolin_blog, an official wechat account
There are several common ways to use threads
- A:
- Method 2:
- Three:
Mode 1, mode 2, and mode 3 startup:
public static void main(String[] args) throws ExecutionException, InterruptedException {
/ / way
MyThread myThread = new MyThread();
myThread.start();
2 / / way
MyRunnable myRunnable = new MyRunnable();
new Thread(myRunnable).start();
3 / / way
MyCallable myCallable = new MyCallable();
FutureTask<String> futureTask = new FutureTask<String>(myCallable) {
@Override
protected void done(a) {
System.out.println("Way three before we start!");
super.done();
System.out.println("Mode three after execution!");
try {
System.out.println("Done internal method 3 return result :" + get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch(ExecutionException e) { e.printStackTrace(); }}};// Start the thread
new Thread(futureTask).start();
System.out.println("Obtain method three return result :" + futureTask.get());
}
Copy the code
Running results:The differences between the three ways:
- extend ThreadI need to override it manually
run
methods - implements RunnableYou need to put the current
runnable
Object toThread
In the - implements Callable<*>Access to
thread
, and cannot be passed directly to thread to startFutureTask
To match, and can passFutureTask.get()
Get the implementationImplements Callable < * >
thecall
The return value of.
The difference between thread.start () and thread.run ()
Here’s another piece of code:
- start:
Client4Thread client4Thread = new Client4Thread(); client4Thread.start(); Copy the code
Running results:
thread:Thread-0 Copy the code
- run:
Client4Thread client4Thread = new Client4Thread(); client4Thread.run(); Copy the code
Running results:
thread:main Copy the code
Conclusion: Calling thread.run () is equivalent to an ordinary class calling a run method without opening child threads
Equivalent to this:
public static class User {
public void run(a) {
System.out.println("User.run"+ Thread.currentThread().getName()); }}Copy the code
Client4thread.run () is equivalent to user.run ()!
Client4Thread client4Thread = new Client4Thread();
// client4Thread.start();
// It has the same effect
client4Thread.run();
//
//
new User().run();
Copy the code
Thread.join() Thread serialization
Let’s take a look at the usage scenario:
Now we have three threads running at the same time. Let’s see what happens:
As you can see, the order of execution is different each time..
If you want it to be synchronized, you can do this:
Conclusion: The purpose of a JOIN is to join threadsserialization
, it should be noted that,join()
Be sure to open it on site (start()
),
Thread.interrupt () Interrupts a Thread
Run code:The running results are as follows:As you can see, although an interrupt signal is sent to the child thread, the thread does not execute the terminal, but lives on.
If you want a Thread to interrupt, simply check for isInterrupted() in Thread
For example:The running results are as follows: The small hole:If you need to be in! isInterrupted()
For example:You can’t do that becauseThread.sleep
The interrupt signal is captured and changed tofalse
And it ended up like this
Eventually, an interrupt exception was caught, but Thread.sleep() arbitrarily changed it.. Simply change the status again when you catch InterruptedException:
For example:Of course it’s not justextend Thread
This way of writing interrupts the thread,implements Runnable
It is also possible to interrupt the thread, for example:
The effect is the same, I will not repeat the show..
Thread data sharing synchronized
Let’s start with a simple example:
There are now2
Two threads need to be paired simultaneouslycount ++
, for example:The result is:You can see that it’s different every time you run it, right?
Why is that?
Because the loop is adding 1000 * 100 times, when two threads are running at the same time, two counts are executed at the same time, so the numbers are always wrong.
Just synchronize it (add a lock), for example:
Common lock writing method:
-
Lock the class of a class:
private static final Object object = new Object(); public static void addCount(a) { for (int i = 0; i < countLength; i++) { synchronized(object) { count++; }}}Copy the code
-
Lock this of the current object
public synchronized void addCount2(a) {... }Copy the code
-
Lock the class of the specified object:
public static void addCount(a) { for (int i = 0; i < countLength; i++) { synchronized(Client2.class) { count++; }}}Copy the code
Thread Isolation (ThreadLocal)
What is thread isolation? Let’s look at the code:But first, the results:As you can see, the effect of each run is not the same
This is because at start, the thread is just ready to tell the JVM that I’m ready to execute. The JVM calls the actual execution
Look at the problem in terms of the last result:
ThreadName:Thread-1 threadIndex:1 count:2
ThreadName:Thread-4 threadIndex:4 count:11
ThreadName:Thread-3 threadIndex:3 count:7
ThreadName:Thread-2 threadIndex:2 count:4
ThreadName:Thread-0 threadIndex:0 count:2
Copy the code
Let’s look at the code first:
In the main method, 5 threads are opened and subscripts are passed in, and MyThreadLocal is added to the table below
Demand analysis:
Since we’re talking about thread isolation, the desired effect should be that if 5 is now coming in, then pass
count+=threadIndex;
Copy the code
The result should be 6, instead of counting the results of other threads to the current thread
ThreadLocal = ThreadLocal = ThreadLocal = ThreadLocal
One was added at startupThread.join()
Cause threads to execute sequentially..
Look directly at the effect:
As you can see, thread isolation is now implemented
If you read the Handler source code, you’ll also see that it uses ThreadLocal internally for thread isolation
Thread isolation, however, isolates loppers to ensure that a thread has only one Looper
Glance athandler
The code:
Use of notify(),notifyAll(), and wait()
Tips: Notify () notifyAll() and wait are properties of Object(), so each class can be called
Here’s how they differ:
- WaitAndNotifyBean:
Wait for a refresh via 'changeName()' by calling 'waitName()'Copy the code
- MyThread:
- Use:
Take a look at the results:
notify | notifyAll |
---|---|
Notify and notifyAll wake up a thread after a wait
Next, increase the dose!
notify | notifyAll |
---|---|
As you can see, the effect is very obvious!
Multiple threads wait case
notify
, only one will refreshawit
, the other threads continue to waitnotifyAll
, will refresh all wait!
NotifyAll notify() and wait() should be placed inside locks.
According to the lock
ReentrantLock
What is reentrant?
int count = 0;
public synchronized void test(a) {
count++;
if (count <= 10) { test(); }}Copy the code
Take synchronized for example. Based on current knowledge,synchronized is bound to be locked recursively because the first time test() is executed, the lock is locked again before it is released
But synchronized turns out to be fine, because synchronized is reentrant, which means that if the same instance is used, it can be re-entered
The same goes for ReentrantLock
Take a look at ReentrantLock in action:The result was the same:The important thing to note here is that when using implicit locks, it must be placed intry { ... } finally { .. }
Block of code
This is done because even if an exception is thrown, the lock will be released and no deadlock will occur
Sample specification:
lock.lock();
try{
count++;
} finally {
lock.unlock();
}
Copy the code
Read-write lock (ReentrantReadWriteLock)
To stand out as ReentrantReadWriteLock, you need a comparison, and synchronized!
Open 3 writer threads and 30 reader threads to simulate the read operation in real development
See how synchronized and read-write locks work in action!
Here’s the code idea:
- StudentImpl
- getThread:
- setThread:
Run:
Synchronized effect and read/write lock comparison:
synchronized | Read-write lock |
---|---|
As can be seen, the effect is very obvious, from the change can also be seen, if you want to do a lot of read and write operations, using read and write lock efficiency will be greatly improved!
Extracurricular knowledge volatile!
Volatile is not the knowledge of Thread, but let’s talk about keywords.
Or a piece of code that makes the difference:
Without volatile:Effect:
As you can see, novolatile
Key words,isRun
Even if it is changed, there is no response in the thread.
Now let’s look at addingvolatile
Key words:Effect:The results are obvious, once markedvolatile
isRun
A variable is notified directly whenever it changesJVM
To change the current state!!
The complete code
Original is not easy, your praise is the biggest support for me!