2011-08-22 37 views
6

Tôi cần xác định biến được chia sẻ trong phương thức main() của lớp Chính của tôi. Tôi cần hai luồng để có thể truy cập vào biến chia sẻ đó. Im tạo các luồng bằng cách thực hiện giao diện Runnable và triển khai phương thức abstract run() trừu tượng của giao diện. Làm thế nào để tôi tham khảo biến chia sẻ được định nghĩa trong phương thức main() của lớp Main từ bên trong phương thức run() được định nghĩa trong lớp của tôi, thực hiện giao diện Runnable? Rõ ràng chỉ cần gọi chúng bằng tên là không hoạt động - khi chúng xuất hiện trong phạm vi của lớp Runnable của tôi.truy cập biến được chia sẻ từ bên trong lớp Runnable

EDIT - xin lỗi, đây là một ví dụ đơn giản

public Class DoThread implements Runnable { 

    public void run(){ 
     sharedVar += 1 
    } 


} 

và trong một file .class riêng biệt:

public Class Main { 

    public static void main(String[] args) { 
     int sharedVar = 0; 

     Thread t1 = new Thread(new DoThread()); 
     Thread t2 = new Thread(new DoThread()); 

     t1.start(); 
     t2.start(); 

     t1.join(); 
     t2.join(); 

    } 


} 

vì vậy tôi cần phải tạo ra một đối tượng để lưu trữ các var chia sẻ trong và sau đó truyền đối tượng đó cho cả các nhà xây dựng DoThread() khi tạo các luồng? Tôi bị nhầm lẫn đôi khi giữa khi java đi bởi ref hoặc đi qua var, vì vậy nếu tôi làm theo cách này, sẽ thay đổi để chia sẻ var bởi t1 được nhìn thấy bởi t2?

+0

Bạn có thể đăng mã của mình không? – SJuan76

+0

Luôn cố gắng đăng một [SSCCE] (http://sscce.org/). –

Trả lời

10

Vâng, nếu bạn khai báo một biến số cục bộ, bạn sẽ không thể tham chiếu đến bất kỳ nơi nào ngoài các lớp được tạo trong phương thức đó.

Bạn đang triển khai thực hiện ở đâu Runnable? Nếu nó nằm trong cùng một lớp, thì bạn có thể biến nó thành một biến thể hiện và đặt main đặt biến trên cùng một cá thể mà bạn đang tạo luồng từ đó hoặc biến nó thành một biến tĩnh. Nếu Runnable được triển khai trong một lớp khác, khi bạn xây dựng một thể hiện của lớp đó, bạn có thể cung cấp dữ liệu cần thiết - không rõ chính xác điều đó có ý nghĩa gì vào thời điểm này ... Như những người khác đã nói, mã sẽ hữu ích. (Ví dụ, làm các chủ đề cần để có thể xem thay đổi trong dữ liệu gốc?)

Ngoài ra, luồng tương đối cao, trong khi việc truyền dữ liệu giữa các lớp là tương đối cơ bản. Nếu bạn mới sử dụng Java, tôi khuyên bạn nên bắt đầu với những thứ dễ dàng hơn luồng.

EDIT: Ví dụ của bạn, bạn nên sử dụng một AtomicInteger, như thế này:

import java.util.concurrent.atomic.AtomicInteger; 

class DoThread implements Runnable { 

    private final AtomicInteger counter; 

    DoThread(AtomicInteger counter) { 
     this.counter = counter; 
    } 

    public void run() { 
     counter.incrementAndGet(); 
    } 
} 

public class Test { 
    public static void main(String[] args) throws InterruptedException { 
     AtomicInteger shared = new AtomicInteger(0); 

     Thread t1 = new Thread(new DoThread(shared)); 
     Thread t2 = new Thread(new DoThread(shared)); 

     t1.start(); 
     t2.start(); 

     t1.join(); 
     t2.join(); 

     System.out.println(shared.get()); // Prints 2 
    } 
} 
+0

cảm ơn jon - tôi đã thêm một ví dụ vào bài đăng gốc^ –

+0

@Dave: Tôi đã đưa ra một ví dụ về cách bạn có thể thay đổi mã của mình. Tôi vẫn nghĩ rằng nếu chia sẻ dữ liệu giữa các đối tượng khác nhau là tương đối mới đối với bạn, có thể bạn chưa sẵn sàng cho những khó khăn bổ sung của luồng chưa. –

7

Mã sẽ hữu ích.

Nếu bạn đang sử dụng một lớp ẩn danh, thì bạn có thể khai báo các biến là final và chúng sẽ có thể truy cập được trong lớp ẩn danh.

public void main(String[] args) { 
    final int myvar = 0; 
    new Thread(new Runnable() { 
     public void run() { 
      System.out.println("myvar: "+myvar); 
     } 
    }).start(); 
} 
2

Bạn cần chuyển tham chiếu đến giá trị được chia sẻ. Nếu nó không phải là một tài liệu tham khảo, bạn cần phải thay đổi nó thành một AtomicReference, AtomicInt vv hoặc một mảng giá trị bạn muốn chia sẻ.

0

Đây là nơi mà PassByRef là hiệu quả hơn. Chuyển tham chiếu biến của bạn tới cả hai trường hợp runnable. Đó là tất cả ... từ đó nó có thể được tham chiếu bên trong phương thức chạy của bạn.

Ví dụ:

Chủ đề th1 = new Thread (Myrunnable (varRef)). Tương tự đối với các chủ đề khác

+0

là những gì tôi đã đề cập trong loại chỉnh sửa của tôi về điều này? –

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