JavaRush /Blog Java /Random-VI /Nghỉ giải lao #160. Đi sâu vào Java ThreadLocal. Lớp máy ...

Nghỉ giải lao #160. Đi sâu vào Java ThreadLocal. Lớp máy quét trong Java

Xuất bản trong nhóm

Đi sâu vào Java ThreadLocal

Nguồn: Devgenios Hôm nay bạn sẽ tìm hiểu về ThreadLocal, một trong những lớp phổ biến được sử dụng để phát triển các ứng dụng Java. Nghỉ giải lao #160.  Đi sâu vào Java ThreadLocal.  Lớp máy quét trong Java - 1

ThreadLocal là gì?

Lớp ThreadLocal lưu trữ các biến cục bộ cho các luồng. Các biến này được cách ly giữa các luồng khác nhau và chỉ có thể được truy cập bằng luồng riêng của chúng. Các trường hợp sử dụng cho ThreadLocal :
  1. Cô lập dữ liệu giữa các chủ đề.
  2. Quản lý phiên cho các kết nối cơ sở dữ liệu.
  3. Lưu trữ thông tin giao dịch chủ đề.

Làm cách nào để sử dụng ThreadLocal?

Hãy xem xét một ví dụ đơn giản.

public static void main(String[] args) {
    //Создаем ThreadLocal
    ThreadLocal<String> local = new ThreadLocal<>();
    //Создаем новый класс Random
    Random random = new Random();
    //Создаем 5 потоков
    IntStream.range(0, 5).forEach(a-> new Thread(()-> {
        //Присваиваем meaning каждому потоку
        local.set(a+"  "+random.nextInt(100));
        System.out.println("Thread number and its local value  "+ local.get());
    }).start());
}
Trong đoạn mã trên, chúng ta tạo một lớp ThreadLocal , tạo 5 luồng, gán giá trị cho ThreadLocal trong mỗi luồng và in. Khi xuất ra ta nhận được: Nghỉ giải lao #160.  Đi sâu vào Java ThreadLocal.  Lớp máy quét trong Java - 2

Có gì dưới mui xe?

Nếu quan sát kỹ, bạn có thể thấy rằng có hai phương thức quan trọng trong ThreadLocal từ ví dụ mã này.
  • công khai T get() {}

  • tập khoảng trống công khai (giá trị T) {}

Hãy xem phương thức setter trong mã nguồn ThreadLocal :

public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
}
Phương thức setter trước tiên lấy luồng hiện tại và gọi phương thức getMap() để lấy lớp ThreadLocalMap . Nếu bản đồ tồn tại, hãy lấy luồng hiện tại t làm khóa, tham số đầu vào làm giá trị và đặt cặp {key:value} thành bản đồ. Nếu không thì hãy tạo một bản đồ . Bây giờ bạn có thể có câu hỏi - ThreadLocalMap là gì ?

static class ThreadLocalMap {
   /**
    * The entries in this hash map extend WeakReference, using
    * its main ref field as the key (which is always a
    * ThreadLocal object).  Note that null keys (i.e. entry.get()
    * == null) mean that the key is no longer referenced, so the
    * entry can be expunged from table.  Such entries are referred to
    * as "stale entries" in the code that follows.
    */
    static class Entry extends WeakReference<ThreadLocal<?>> {
       /** The value associated with this ThreadLocal. */
       Object value;
       Entry(ThreadLocal<?> k, Object v) {
           super(k);
           value = v;
       }
    }
}
ThreadLocalMap là một lớp tĩnh bên trong ThreadLocal định nghĩa lớp Entry để lưu trữ dữ liệu. Entry sử dụng phiên bản ThreadLocal làm khóa và đặt giá trị mà chúng tôi chuyển. Nếu điều này nghe có vẻ quá khó hiểu vào thời điểm này, chỉ cần nhớ rằng chính lớp Entry trong ThreadLocalMap thực hiện việc lưu trữ thực tế các giá trị. Để lấy dữ liệu từ ThreadLocal, chúng tôi sử dụng phương thức getter :

public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
}
Trong phương thức getter , chúng ta sẽ sử dụng currentThread làm khóa để lấy ThreadLocalMap . Sau đó, bản đồ sẽ getEntry() dựa trên phiên bản ThreadLocal và trả về phiên bản Entry và sau đó là giá trị được lưu trữ. Đây là một sơ đồ để giúp bạn tìm ra nó: Nghỉ giải lao #160.  Đi sâu vào Java ThreadLocal.  Lớp máy quét trong Java - 3Nghỉ giải lao #160.  Đi sâu vào Java ThreadLocal.  Lớp máy quét trong Java - 4
  1. Mỗi luồng duy trì một tham chiếu đến ThreadLocalMap .

  2. ThreadLocalMap là một lớp tĩnh bên trong của ThreadLocal và sử dụng lớp Entry để lưu trữ.

  3. Khóa ThreadLocalMap là một phiên bản của ThreadLocal và có thể có nhiều ThreadLocals .

  4. Bản thân ThreadLocal không lưu trữ giá trị nhưng nó là khóa cho luồng sẽ giúp lấy giá trị từ ThreadLocalMap .

Lưu ý rằng tốt hơn hết bạn nên loại bỏ ThreadLocal để tránh OOM (Lỗi hết bộ nhớ) do tham chiếu “yếu” trong lớp Entry .

Lớp máy quét trong Java

Nguồn: Medium Bài đăng này sẽ giúp bạn làm quen với lớp Scanner trong Java. Nghỉ giải lao #160.  Đi sâu vào Java ThreadLocal.  Lớp máy quét trong Java - 5Lớp Scanner trong Java là lớp chúng ta sử dụng khi muốn lấy giá trị từ người dùng. Cách dễ nhất để hiểu nó là bằng các ví dụ, vì vậy chúng ta hãy xem xét nó rõ ràng hơn. Tạo lớp Máy quét là một trong ba bước chúng tôi thực hiện để nhận giá trị từ người dùng. Bước đầu tiên là tạo một đối tượng từ lớp máy quét.

Scanner scan=new Scanner(System.in);
Bây giờ chúng ta có một đối tượng máy quét. Đối tượng này sẽ có các thuộc tính Scanner từ lớp Scanner . Sau bước đầu tiên, người dùng đã có thể nhập giá trị mong muốn, nhưng nếu chúng tôi không hướng dẫn người dùng và hiển thị giá trị trong bảng điều khiển hoặc trong ứng dụng thì khả năng sử dụng sẽ không tốt lắm. Vì vậy, tốt hơn hết bạn nên thông báo và hướng dẫn người dùng:

System.out.println("Please enter your name");    
String name=scan.next();   
System.out.println("Your Name:"+name);
Trong dòng đầu tiên, chúng tôi hỏi người dùng những gì chúng tôi muốn ở anh ấy. Điều này thực sự không liên quan gì đến máy quét, nhưng việc đưa ra gợi ý cho người dùng của bạn luôn là điều tốt. Ở dòng thứ hai chúng ta sẽ gán giá trị mà người dùng nhập vào dữ liệu và lưu lại để có thể sử dụng sau này. Ở dòng cuối cùng, chúng ta thấy rằng chúng ta có thể tùy ý sử dụng giá trị nhận được từ người dùng. Hãy thêm một vài chi tiết vào mã của chúng tôi:

System.out.println("Please enter your last name");
  
String lastName=scan.next();
  
System.out.println("Your Name " + name + " " + "Your Last Name" + lastName);
Về cơ bản, chúng tôi lặp lại hai dòng trước, hỏi giá trị của người dùng và lưu nó. Bây giờ ở dòng cuối cùng, chúng tôi đã sử dụng hai giá trị mà chúng tôi đã lấy từ người dùng và hiện được sử dụng cùng nhau.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION