2012-11-22 41 views
5

Dưới đây bạn có thể thấy biến tĩnh counter trong lớp Java.Cập nhật biến tĩnh Java

Câu hỏi đặt ra là khi nào biến này sẽ đặt lại? Ví dụ, khi tôi khởi động lại chương trình, máy tính. Các kịch bản có thể khác mà nó có thể đặt lại là gì?

Một câu hỏi khác là: điều gì có thể là lý do cho biến này tăng ít hơn số lần hàm thực hiện() được thực thi? Ví dụ, nó có thể là một cái gì đó với việc bắt đầu nhiều quá trình của lớp java Whatever? Hoặc nó có thể là một cái gì đó với nhiều chủ đề/máy chủ, vv?

class Whatever { 

    static int counter = 0; 

    function do() { 
     counter++; 
     //... 
    } 

} 

Câu hỏi bổ sung: Nếu có nhiều chủ đề thực thi hàm do(), biến số đếm sẽ hoạt động như thế nào? Nó sẽ nhỏ hơn số lần hàm do() được thực thi?

+0

Biến 'tĩnh' chỉ được khởi tạo một lần, khi bắt đầu thực hiện chương trình. – Maroun

+0

bộ đếm 'của bạn là gói riêng tư, vì vậy bất kỳ lớp nào trong cùng một gói có thể gán một giá trị tùy ý cho nó. – jlordo

+0

BTW, 'do' là từ khóa dành riêng và * không thể * được sử dụng làm tên phương thức. – jlordo

Trả lời

2

Biến tĩnh sẽ được khởi tạo lại khi bạn khởi động lại ứng dụng.

2

Theo JLS:

Nếu một lĩnh vực được khai báo tĩnh, tồn tại đúng một hiện thân của lĩnh vực này, dù có bao nhiêu trường hợp (có thể không) của lớp cuối cùng có thể được tạo ra. Trường tĩnh, đôi khi được gọi là biến lớp, được nhập thể khi lớp được khởi tạo

Vì vậy, câu trả lời cho câu hỏi đầu tiên của bạn. tức là khi lớp học được tải :)

Theo câu hỏi thứ hai, không có. nếu biến được khai báo riêng tư. Sau đó, truy cập duy nhất là thông qua phương pháp vì đóng gói.

Biến tĩnh kéo dài cho đến khi JVM tắt.

0

1) Biến được đặt (đặt lại) khi lớp được tải. Ngoài việc tắt JVM, một số máy chủ tải lớp trong các ứng dụng khác nhau (ví dụ: các ứng dụng web Tomcat) và một số máy chủ cho phép khởi động lại chúng.

2) Sửa đổi đồng thời theo chuỗi. Nhưng nó rất hiếm, trừ khi bạn sử dụng nó rất nhiều. Sử dụng synchronized cho chức năng/khối.

+0

Nếu có nhiều chủ đề truy cập vào nó, biến truy cập sẽ như thế nào? Nó sẽ nhỏ hơn số lần hàm do() được thực thi? – jQguru

+0

Có. Hãy nghĩ về 'counter' là 2; 'thread1' thực hiện thao tác, để tính toán ++ lấy 2 và thêm 3, nhưng trước khi thay thế 2 bằng 3' thread2' bắt đầu hoạt động, truy lục 'counter' vẫn là 2, và tính kết quả là 3. Trong kết thúc cả hai chủ đề sẽ thiết lập giá trị của 'counter' đến 3, trong khi một trong số họ nên đã đặt nó thành 4. Nó được gọi là Concurrency hoặc điều kiện chạy. – SJuan76

1

counter không phải là biến riêng tư. Vì vậy, có thể là giá trị này được thay đổi bởi một số lớp khác.

Biến này sẽ được đặt lại bất cứ khi nào chương trình của bạn (hoặc cụ thể là vùng chứa/jvm) được khôi phục.

0

Câu hỏi đặt ra là khi nào biến này sẽ đặt lại?

Biến tĩnh có thể được đặt lại bằng phương thức tùy chỉnh reset(). Nếu bạn nói chương trình khởi động lại, về mặt lý thuyết biến đó sẽ được khởi tạo thành giá trị của nó không được khởi tạo lại vì nó không giống nhau (bạn khởi động lại chương trình).

0
class Foo { // in same package 
public static void main(String[] args) { 
    Whatever w = new Whatever(); 
    for (int i = 0; i < 1000; i++) { 
     w.do(); 
    } 
    Whatever.counter = -1; 
} 

đây được gọi 1000 lần, nhưng counter sẽ có giá trị ở cuối.

Tôi đã sử dụng do() như bạn trong ví dụ của mình, nhưng lưu ý rằng không phải là tên phương thức hợp lệ, bởi vì đó là từ khóa cho vòng lặp trong khi thực hiện.

0

Biến tĩnh có nghĩa là chỉ có một hiện thân của trường đó trong khi thực thi chương trình. Nó được nạp khi lớp được khởi tạo.

Đối với câu hỏi thứ hai, biến của bạn không an toàn bởi vì nhiều chuỗi có thể truy cập cùng một lúc. Ngay cả khi bộ đếm của bạn dễ bay hơi, bạn vẫn phải đối mặt với vấn đề đồng thời. Bạn có ba tùy chọn, được cung cấp ví dụ và yêu cầu của bạn:

Nếu yêu cầu duy nhất của bạn là thao tác biến và phần còn lại của mã sẽ không phụ thuộc vào việc bạn có thể sử dụng đồng bộ hóa (giết bay với pháo) hoặc AtomicInteger (lựa chọn với hiệu suất tốt hơn):

static synchronize int counter = 0; 
// or 
static AtomicInteger counter = new AtomicInteger(); 

Nếu phần còn lại của mã của bạn là phụ thuộc vào truy cập của bạn, bạn phải sử dụng một đối tượng khóa hoặc đồng bộ hóa phương pháp của bạn:

class Whatever { 

    static int counter = 0; 

    synchronize function do() { 
     counter++; 
     if(counter < 10){ 
      // do something 
     } 
    } 
} 

// or 

class Whatever { 

    static int counter = 0; 
    static final Object _lock = new Object(); 

    function do() { 
     synchronized (_lock) { 
      counter++; 
      if(counter < 10){ 
       // do something 
      } 
     } 
    } 
} 

này là op tions hiện đang ở trong đầu tôi, nhưng có lẽ còn nhiều hơn nữa.

Các vấn đề liên quan