2014-12-30 18 views
7

I yêu thích Các luồng Java 8. Họ là trực quan, mạnh mẽ và thanh lịch. Nhưng họ có một nhược điểm chính là IMO: họ thực hiện gỡ lỗi nhiều hơn (trừ khi bạn có thể giải quyết vấn đề của mình bằng cách chỉ gỡ lỗi các biểu thức lambda, được trả lời here).Các sự cố khi sử dụng các trình gỡ rối tương tác với các luồng Java 8

Hãy xem xét hai mảnh tương đương sau:

int smallElementBitCount = intList.stream() 
    .filter(n -> n < 50) 
    .mapToInt(Integer::bitCount) 
    .sum(); 

int smallElementBitCount = 0; 
for (int n: intList) { 
    if (n < 50) { 
     smallElementBitCount += Integer.bitCount(n); 
    } 
} 

tôi thấy người đầu tiên rõ ràng hơn nhiều và gọn gàng hơn. Tuy nhiên, hãy xem xét tình huống mà kết quả không phải là những gì bạn mong đợi. Bạn làm nghề gì?

Trong kiểu lặp lại truyền thống, bạn đặt điểm ngắt trên đường dây totalBitCount += Integer.bitCount(n); và đi qua từng giá trị trong danh sách. Bạn có thể xem phần tử danh sách hiện tại là gì (xem n), tổng hiện tại (xem totalBitCount) và, tùy thuộc vào trình gỡ lỗi, giá trị trả về của Integer.bitCount là gì.

Trong kiểu luồng mới, tất cả điều này là không thể. Bạn có thể đặt điểm ngắt trên toàn bộ câu lệnh và chuyển sang phương thức sum. Nhưng nói chung điều này gần như vô dụng. Trong tình huống này trong thử nghiệm của tôi, ngăn xếp cuộc gọi của tôi là 11 sâu, trong đó 10 là các phương thức java.util mà tôi không quan tâm. Không thể duyệt qua các vị từ kiểm tra mã hoặc thực hiện ánh xạ.

Ghi chú trong câu trả lời cho Debugging streams question rằng trình gỡ lỗi lặp hoạt động khá tốt để phá vỡ các biểu thức lambda (chẳng hạn như vị từ n < 50). Nhưng trong nhiều trường hợp, điểm ngắt thích hợp nhất không nằm trong một lambda.

Rõ ràng đây là một đoạn mã đơn giản để gỡ lỗi. Nhưng một khi các tùy chọn giảm và các bộ sưu tập được thêm vào, hoặc các chuỗi bộ lọc và bản đồ phức tạp hơn, nó có thể trở thành một cơn ác mộng để gỡ lỗi.

Tôi đã thử điều này trên NetBeans và Eclipse và cả hai dường như có cùng vấn đề. Trong vài tháng qua, tôi đã sử dụng để gỡ lỗi bằng cách sử dụng các cuộc gọi .peek để ghi các giá trị tạm thời hoặc chuyển các bước tạm thời vào các phương thức được đặt tên riêng của chúng hoặc, trong trường hợp cực đoan, tái cấu trúc dưới dạng lặp cho đến khi mọi lỗi được sắp xếp. Điều này làm việc nhưng nó nhắc nhở tôi rất nhiều những ngày cũ xấu trước khi IDE hiện đại với debuggers tương tác tích hợp khi bạn đã phải phân tán các báo cáo printf thông qua mã.

Chắc chắn có cách nào tốt hơn.

Cụ thể tôi muốn biết:

  • đã khác gặp vấn đề này giống nhau không?
  • có bất kỳ trình gỡ rối tương tác 'phát hiện luồng' nào có sẵn không?
  • có kỹ thuật nào tốt hơn để gỡ lỗi kiểu mã này không?
  • đây có phải là lý do để hạn chế việc sử dụng luồng cho các trường hợp đơn giản không?

Bất kỳ kỹ thuật nào bạn đã tìm thấy thành công sẽ được đánh giá cao.

+0

Điều này đã được đánh dấu là trùng lặp nhưng trong chính câu hỏi tôi tham khảo câu hỏi khác và giải thích rằng tôi đang hỏi điều gì đó khác - tôi đặc biệt không muốn đột nhập bên trong biểu thức lambda. Tôi sẽ cố gắng làm rõ hơn trong câu hỏi. – sprinter

+0

Các lời xin lỗi - mở cửa trở lại. Giám sát kết thúc của tôi. –

+0

Câu hỏi này phù hợp với ba trong số năm lý do có sẵn, nhưng tôi không thể tự mình mang theo VTC. Có vẻ như quá quan trọng, bằng cách nào đó. –

Trả lời

2

Tôi không hoàn toàn chắc chắn có một công việc khả thi xung quanh cho vấn đề này. Bằng cách sử dụng các luồng, bạn đang ủy nhiệm lặp lại hiệu quả (và mã liên quan) cho VM theo như tôi hiểu nó, do đó đẩy quá trình vào một hộp đen là chính luồng đó.

Ít nhất từ ​​những gì tôi đã đọc về chúng. Đây là những gì đã xảy ra xung quanh mã lambda cho tôi (nếu chúng đủ phức tạp, rất khó để theo dõi những gì đang xảy ra xung quanh chúng). Tôi sẽ rất quan tâm đến bất kỳ tùy chọn gỡ lỗi nào trên mạng, nhưng tôi chưa tìm thấy bất kỳ tùy chọn nào.

+0

Giống như ở đây, thật không may. – afk5min

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