На самом деле, нецелесообразно сравнивать Runnable
и Thread
друг с другом.
У этих двух есть зависимость и взаимосвязь в многопоточности, как Wheel and Engine
отношение автомобиля.
Я бы сказал, есть только один способ многопоточности с двумя шаги. Позвольте мне высказать свою мысль.
Runnable: при реализации interface Runnable
это означает, что вы создаете что-то, что run able
в другом потоке. Теперь создание чего-то, что может работать внутри потока (runnable внутри потока), не означает создание Thread. Таким образом, класс MyRunnable
- не что иное, как обычный класс с методом void run
. И это объекты будут обычными объектами только с методом run
, который будет нормально выполняться при вызове. (если мы не передадим объект в потоке).
Тема: class Thread
, я бы сказал, очень специальный класс с возможностью запуска нового потока, который фактически позволяет многопоточность через start()
метод.
Почему не разумно сравнивать? Потому что нам нужны оба для многопоточности.
Для многопоточности нам нужны две вещи:
Так что технически и теоретически оба из них необходимы, чтобы начать поток, один запустится, и один сделает
Вот почему вы не можете запустить нить с MyRunnable
, вам нужно передать ее в экземпляр Thread
.
Но можно создать и запустить поток только с помощью class Thread
, потому что класс Thread
реализует Runnable
, поэтому мы все знаем, что Thread
также является Runnable
внутри.
Наконец Thread
] и Runnable
дополняют друг друга для многопоточности, не являющейся конкурентом или заменой.
Если вы уверены, что текущая папка вашего приложения является папкой jar, вы можете просто вызвать InputStream f = new FileInputStream("test.jpg");
Методы getResource
будут загружать файлы, используя загрузчик классов, а не через файловую систему. Вот почему ваш подход (1) не удался.
Если папка с вашим *.jar
и файлом изображения находится в пути к классам, вы можете получить ресурс изображения так, как если бы он был в пакете по умолчанию:
class.getClass().getResourceAsStream("/test.jpg");
Beware : Изображение загружается в загрузчик классов, и пока приложение запускается, изображение не выгружается и не загружается из памяти, если вы загружаете его снова.
Если путь, содержащий файл jar, не указан в пути к классам ваш подход к получению пути jarfile хорош. Но затем просто войдите в файл непосредственно через URI, открыв на нем поток:
URL u = this.getClass().getProtectionDomain().getCodeSource().getLocation();
// u2 is the url derived from the codesource location
InputStream s = u2.openStream();
Используйте этот учебник , чтобы помочь вам создать URL-адрес для одного файла в файле jar.
Вот пример:
String jarPath = "/home/user/myJar.jar";
String urlStr = "jar:file://" + jarPath + "!/test.jpg";
InputStream is = null;
try {
URL url = new URL(urlStr);
is = url.openStream();
Image image = ImageIO.read(is);
}
catch(Exception e) {
e.printStackTrace();
}
finally {
try {
is.close();
} catch(Exception IGNORE) {}
}