In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article introduces the relevant knowledge of "java multithreaded locking and the use of Condition classes". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Code
Import java.util.Arrays;import java.util.LinkedList;import java.util.List;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.ReentrantLock;import java.util.function.Predicate;public class Main {public static void main (String [] args) throws InterruptedException {MyBlockingQueue queue = new MyBlockingQueue (1); for (int I = 0; I
< 10; i++) { int data = i; new Thread(() ->{try {queue.enqueue (data);} catch (InterruptedException e) {e.printStackTrace ();}}). Start ();} System.out.println ("1111111"); for (int item0 int I {try {queue.dequeue ();} catch (InterruptedException e) {e.printStackTrace ();}}). Start ();}} public static class MyBlockingQueue {int size;// maximum capacity ReentrantLock lock = new ReentrantLock (true); LinkedList list=new LinkedList () / / implementation at the bottom of the queue Condition notFull = lock.newCondition (); / / wait condition when the queue is full Condition notEmpty = lock.newCondition (); / / wait condition public MyBlockingQueue (int size) {this.size = size;} public void enqueue (E) throws InterruptedException {lock.lock (); try {while (list.size () = = size) / / queue is full, wait for notFull.await () on notFull condition; list.add (e) / / join: join the end of the list System.out.println ("queue:" + e); notEmpty.signal (); / / notify the thread waiting on the notEmpty condition} finally {lock.unlock ();}} public E dequeue () throws InterruptedException {E; lock.lock (); try {while (list.size () = = 0) notEmpty.await (); e = list.removeFirst (); / / dequeue: remove the list header element System.out.println ("out:" + e) NotFull.signal (); / / notify the thread waiting on the notFull condition return e;} finally {lock.unlock ();}}
The main function starts 20 threads, and the first 10 join the team and the last 10 are out of the team. We can see, ah, the results may be output.
New Thread (()-> {try {queue.enqueue (data);} catch (InterruptedException e) {e.printStackTrace ();}}) .start ()
Notice the thread implementation, which is the lambda expression implementation Runable interface.
Team up: 0 out: 0 team: 2 team: 2 team: 1 team: 1 team: 3 team: 3 team: 4 team: 4 team: 5 team: 5 team: 6 team: 6 team: 7 team: 7 team: 8 team: 8 team: 9 team: 9
You can see that before the first queuing, 1111111 has a queue capacity of 1, which means that only the first of the first 10 queuing processes is successful, and all the others are blocked.
And the order of going out and joining the team is in circular order, indicating that the lock is acquired according to the request order, first-come-first-served, which means fair lock. In fact, ReentrantLock can be either a fair lock or an unfair lock. When initializing, inputting true into the constructor is a fair lock, and false is an unfair lock.
As for what a reentrant lock is, you can take a look at this https://www.jb51.net/article/175192.htm, article, which is an example of a reentrant lock.
There is a very strange line of code, lock.lock (); I am curious about what happened to this line of code like me. A lot of people on the Internet talk about getting a lock, but "getting" this is really difficult and unspecific, so I imagined it myself, and it felt like a picture like this:
Combined with my superficial experience, jvm has only one ready queue, and the threads in the ready queue use cpu resources according to the queue order. If there is no lock, then all threads can get the resources in order, but because of the object-oriented, it is difficult to directly control the queue order of the threads in the ready queue, so you need to add locks to control the running order of the threads to ensure that the processing logic is correct. (in fact, it is not such a strict queue. If a thread in the ready state is an unfair lock, it will run randomly. It is just a queue. In fact, it is to express the ready state.)
Combined with the lock () method of the code, if a thread enters cpu and calls lock (), if the lock has not been acquired by another thread, then the thread can use cpu time. If the lock has been acquired by another thread, then the thread will block and enter the blocking queue. In this way, the word "get" is not difficult to understand, it is just a mark. Then the lock () method simply determines whether the current thread is using cpu time or entering the blocking queue.
Taking a look at the unlock () method, with the help of the figure above, this is also easy to understand, which is actually taking the thread at the head of the blocking queue out of the queue and entering the ready queue.
It can be guessed that if there are multiple lock instances in the running process, then how many threads may be blocked? in addition to using multiple locks, there are other ways to increase the blocking thread, that is, using the Condition class. It should be pointed out that the await () method of the condition class blocks the current thread, and then automatically unlocks the lock acquired by the current thread (this is especially important), switching threads, if there is a wake-up in other threads. Then after being awakened, the thread will continue to run down from the location of await (), so it is usually used in conjunction with the while loop. If a thread is awakened, it will also re-acquire the lock it acquired before. If the lock has been acquired by another thread and has not been unlocked, the wake-up will go wrong and an inexplicable error will occur. So you need to set a volatile variable to detect the running state of the thread, so the await () method should be checked before and after.
Here is a question from leetcode, which requires that the condition class be used to write
Meaning of the title:
Write a program that outputs a string representing this number from 1 to n, but:
If this number is divisible by 3, output "fizz".
If this number is divisible by 5, output "buzz".
If this number is divisible by both 3 and 5, output "fizzbuzz".
For example, when n = 15, the output: 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizzbuzz.
Solution:
Import java.util.Random;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class Main {static void printFizz (int x) {System.out.printf ("% d:Fizz,\ n", x);} static void printBuzz (int x) {System.out.printf ("% d:Buzz,\ n", x) } static void printFizzBuzz (int x) {System.out.printf ("% d:FizzBuzz,\ n", x);} static void printaccpt (int x) {System.out.printf ("% d,\ n", x);} static volatile int now=1; static ReentrantLock lock=new ReentrantLock (); static Condition k1=lock.newCondition (); public static void test (int n) {new Thread (()-> {while (nown) throw new InterruptedException (); k1.await (); if (now > n) throw new InterruptedException ();} printFizz (now); now++ K1.signalAll ();} catch (InterruptedException e) {break; / / e.printStackTrace ();} finally {lock.unlock ();}} System.out.println ("Thread 1 is over");}) .start (); new Thread ()-> {while (nown) throw new InterruptedException (); k1.await (); if (now > n) throw new InterruptedException ();} printBuzz (now); now++; k1.signalAll ();} catch (InterruptedException e) {break; / / e.printStackTrace () } finally {lock.unlock ();}} System.out.println ("Thread 2 is over");}. Start (); new Thread (()-> {while (nown) throw new InterruptedException (); k1.await (); if (now > n) throw new InterruptedException ();} printFizzBuzz (now); now++; k1.signalAll ();} catch (InterruptedException e) {break; / / Thread.interrupted (); / / e.printStackTrace ();} finally {lock.unlock () } System.out.println ("Thread 3 is over");} start (); new Thread (()-> {while (nown) throw new InterruptedException (); k1.await (); if (now > n) throw new InterruptedException ();} printaccpt (now); now++; k1.signalAll ();} catch (InterruptedException e) {break; / / Thread.interrupted (); / / e.printStackTrace ();} finally {lock.unlock ();} System.out.println ("Thread 4 is over") }. Start ();} public static void main (String [] args) throws InterruptedException {test (30);}}
This is the end of the introduction of "java multithreaded locks and examples of the use of Condition classes". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.