Thread
класс, вы потеряли свой шанс и не можете расширять или наследовать другой класс на Java. Thread
, чем используем интерфейс Runnable
. Интерфейс Runnable
представляет собой Task
, который может быть выполнен либо обычным Thread
, либо Executors
или любые другие средства. Таким образом, логическое разделение Task
как Runnable
, чем Thread
, является хорошим конструктивным решением. Runnable
означает, что мы можем повторно использовать задачу, а также иметь возможность выполнять ее с разных средств. Поскольку вы не можете перезапустить Thread
после его завершения, снова Runnable
vs Thread
для задачи, Runnable
является победителем. Executors
принимает Runnable
] как Task
, и у них есть рабочий поток, который выполняет эту задачу. Thread
- дополнительные накладные расходы только для представления функции Task
, которая может быть легко выполнена с помощью Runnable
. См. также lazy_static , что делает вещи немного более эргономичными. Это по существу то же самое, что и статическая Once
для каждой переменной, но обертывает ее типом, который реализует Deref
, чтобы вы могли получить к нему доступ, как обычная ссылка.
Использование выглядит так ( из документации ):
#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;
lazy_static! {
static ref HASHMAP: HashMap<u32, &'static str> = {
let mut m = HashMap::new();
m.insert(0, "foo");
m.insert(1, "bar");
m.insert(2, "baz");
m
};
static ref COUNT: usize = HASHMAP.len();
static ref NUMBER: u32 = times_two(21);
}
fn times_two(n: u32) -> u32 { n * 2 }
fn main() {
println!("The map has {} entries.", *COUNT);
println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
Обратите внимание, что autoderef означает, что вам даже не нужно использовать *
всякий раз, когда вы вызываете метод для вашей статической переменной. Переменная будет инициализирована в первый раз, когда она Deref
'd.
Однако lazy_static переменные неизменяемы (поскольку они находятся за ссылкой). Если вы хотите изменить статичность, вам нужно будет использовать Mutex
:
lazy_static! {
static ref VALUE: Mutex<u64>;
}
impl Drop for IsFoo {
fn drop(&mut self) {
let mut value = VALUE.lock().unwrap();
*value += 1;
}
}
#[test]
fn test_drops_actually_work() {
// Have to drop the mutex guard to unlock, so we put it in its own scope
{
*VALUE.lock().unwrap() = 0;
}
{
let c = CBox;
c.set(IsFoo);
c.set(IsFoo);
c.poll(/*...*/);
}
assert!(*VALUE.lock().unwrap() == 2); // Assert that all expected drops were invoked
}