Там, кстати, не собираются делать аналог try-with-resources?
Нет, и не думаю, что станут: try-with-resources работает только в рамках вызова процедуры и одного потока (одной горутины) — слишком узкоспециализированный механизм. Кроме того, try-with-resources в Java работает только если класс реализует
interface AutoCloseable {
void close() throws Exception
}
а разные «ресурсы» могут иметь разные методы «захвата/освобождения» в соответствии с их семантикой: Open/Close, Lock/Unlock, Create/Delete и т.п. Либо заставлять всех использовать всегда один метод (Close, там или Release) — как-то тупо. Вводить в язык явное понятие ресурса с каким-нибудь спец-синтаксисом, типа помечать освобождающий метод каким-нибудь ключевым словом или спец-символом — ну хз. И это всё равно никак не поможет с разделяемыми ресурсами, например:
package main
import (
"fmt"
"sync"
"time"
)
const nWorkers = 5
func main() {
fmt.Println("ok1:")
ok1()
fmt.Println("\nok2:")
ok2()
fmt.Println("\nnot ok:")
notOk()
}
func ok1() {
var wg sync.WaitGroup
wg.Add(nWorkers) // acquire
for i := 0; i < nWorkers; i++ {
go func(x int) {
defer wg.Done() // release
doSomeWork(x)
}(i)
}
wg.Wait()
}
func ok2() {
var wg sync.WaitGroup
for i := 0; i < nWorkers; i++ {
wg.Add(1) // acquire
go func(x int) {
defer wg.Done() // release
doSomeWork(x)
}(i)
}
wg.Wait()
}
func notOk() {
var wg sync.WaitGroup
for i := 0; i < nWorkers; i++ {
go func(x int) {
wg.Add(1) // acquire
defer wg.Done() // release
doSomeWork(x)
}(i)
}
wg.Wait()
}
func doSomeWork(x int) {
<-time.After(1 * time.Second)
fmt.Println("done #", x)
}
=>
ok1:
done # 2
done # 0
done # 4
done # 3
done # 1
ok2:
done # 0
done # 2
done # 1
done # 3
done # 4
not ok:
Program exited.
try-with-resources тут никак не поможет, т.к. позволяет описать только вариант notOk.
А в JDK, ЕМНИП, у HttpURLConnection освобождающий метод называется disconnect, а не close и соответствено класс не реализует AutoCloseable и использовать его в try-with-resources нельзя :facepalm: