当线程启动时,JVM会在该线程上调用Java Thread的run()方法.要给线程做一些事情,你可以创建一个Thread的子类并覆盖它的run()方法,或者(首选)你可以为线程的构造函数提供一个Runnable.没关系.
我正在制作一个Thread的子类并重写run,我意识到我无法使该方法受到保护,因为Thread.run()是公共的.然后我意识到了原因:它必须是公共的,因为Thread实现了Runnable.但为什么它实现了Runnable?
这似乎不符合逻辑.一个线程是可启动的(来自当前线程),但是你没有像运行()一个Runnable(来自当前线程)那样运行它; 线程自己运行(在自己的线程上).如果你手动调用Thread的run方法,那么你不是将它用作Thread,只是一个重量级的Runnable.
由于这种设计,任何可以访问Thread对象的代码都可以调用它的公共运行方法,并可能潜入代码,这些代码不是公开的,或者设计为以这种方式调用.它还允许这样的非常奇怪的事情:
Thread.currentThread.run();
Run Code Online (Sandbox Code Playgroud)
Thread实现Runnable是否有合法用途,我没有看到?
Java Thread本身实现了Java Runnable!并且根据Internet上的大多数专家,实现Runnable比扩展Thread更受欢迎!即使我们不能在Thread类的线程意义上使用Runnable!
那么为什么我们更喜欢实现Runnable过度扩展,Thread因为在这两种情况下,通过调用一个Thread实现的方法(即start()或者run())来说明实际的线程,尽管在Thread我们没有真正"扩展" Thread仅通过覆盖run()方法的功能的情况下?
如果我听起来很混乱,我道歉......
在现有的Android项目中,我遇到了以下代码(我插入了调试垃圾)
ImageView img = null;
public void onCreate(...) {
img = (ImageView)findViewById(R.id.image);
new Thread() {
public void run() {
final Bitmap bmp = BitmapFactory.decodeFile("/sdcard/someImage.jpg");
System.out.println("bitmap: "+bmp.toString()+" img: "+img.toString());
if ( !img.post(new Runnable() {
public void run() {
System.out.println("setting bitmap...");
img.setImageBitmap(bmp);
System.out.println("bitmap set.");
}
}) ) System.out.println("Runnable won't run!");
System.out.println("runnable posted");
}
}.start();
Run Code Online (Sandbox Code Playgroud)
Android开发的新手,并且已经开始搜索,我知道这是在不阻塞主(UI)线程的情况下执行操作的方法,同时仍然在解码后在UI线程上设置图像.(至少根据android-developers)(我已通过Thread.currentThread().getName()在各个地方登录验证)
现在有时图像不会出现,stdout只说
I/System.out( 8066): bitmap: android.graphics.Bitmap@432f3ee8 img: android.widget.ImageView@4339d698
I/System.out( 8066): runnable posted
Run Code Online (Sandbox Code Playgroud)
没有来自Runnable的消息的痕迹.所以看起来Runnable没有run(),尽管img.post()返回true.拉入ImageView onCreate()并声明它final …
我有以下内容:
Runnable done = new Runnable()
{
public void run()
{
System.out.println("Hello");
}
};
Run Code Online (Sandbox Code Playgroud)
然后在我的Android活动中,我会称之为:
runOnUIThread(done);
Run Code Online (Sandbox Code Playgroud)
然后我打电话给你.但是,我希望"Hello"不要硬编码,所以我可以传入它.否则我将必须为我想要打印的每个字符串都有一个这样的声明.
(这实际上是一个android问题,但是它缩小到基本Java,所以更容易回答)
谢谢
我有一个需要执行两个操作的函数,一个快速完成,另一个需要很长时间才能运行.我希望能够将长时间运行的操作委托给一个线程,我不在乎线程何时完成,但线程需要完成.我实现了如下所示,但是,我的第二次操作永远不会完成,因为函数在start()调用之后退出.我如何确保函数返回但第二个操作线程也完成其执行并且不依赖于父线程?
public void someFunction(String data)
{
smallOperation()
SecondOperation a = new SecondOperation();
Thread th = new Thread(a);
th.Start();
}
class SecondOperation implements Runnable
{
public void run(){
// doSomething long running
}
}
Run Code Online (Sandbox Code Playgroud) 这些方法(类)之间有什么区别?
我想运行一个每5秒运行一次的应用程序,当它完成时清除内存,以及当cpu处于待机模式时,你可以运行该应用程序.因此应用程序不受唤醒锁定.
问候,
沙夫卡特
我试图理解这里的代码,特别是匿名类
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
final long start = mStartTime;
long millis = SystemClock.uptimeMillis() - start;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
if (seconds < 10) {
mTimeLabel.setText("" + minutes + ":0" + seconds);
} else {
mTimeLabel.setText("" + minutes + ":" + seconds);
}
mHandler.postAtTime(this,
start + (((minutes * 60) + seconds + 1) * 1000));
}
}; …Run Code Online (Sandbox Code Playgroud) 作为练习,我尝试创建一个隐式转换,它将接受一个函数并生成一个Runnable.这样你就可以调用接受Runnable对象的Java方法,并像封闭一样使用它们.
隐式转换很容易:
implicit def funToRunnable(fun : Unit) = new Runnable() { def run = fun }
Run Code Online (Sandbox Code Playgroud)
但是我不知道怎么称呼它.如何传入一个返回Unit的无参数函数,而不是立即进行评估?例如,我想要以下内容来打印"12",而是打印"21"因为print("2")一次评估.
var savedFun : Runnable = null
def save(r : Runnable) = { savedFun = r }
save(print("2"))
print("1")
savedFun.run()
Run Code Online (Sandbox Code Playgroud)
如何告诉编译器将其print("2")视为函数的主体,而不是立即进行评估?我试过的一些可能性,比如
save(() => print("2"))
Run Code Online (Sandbox Code Playgroud)
要么
save(=> print("2"))
Run Code Online (Sandbox Code Playgroud)
不是合法的语法.
有没有简单的解决方案在新线程中使用JPA将数据保存到数据库中?
我的基于Spring的Web应用程序允许用户管理计划任务.在运行时,他可以创建和启动预定义任务的新实例.我正在使用spring的TaskScheduler,一切运行良好.
但我需要将每个已触发任务的布尔结果保存到数据库中.我怎样才能做到这一点?
编辑:我必须概括我的问题:我需要从任务中调用我的@Service类的方法.因为在保存到数据库之前必须"处理"任务结果.
编辑2:我的问题代码的简化版本来到这里.从调度程序调用saveTaskResult()时,将打印出消息,但不会将任何内容保存到db中.但每当我从控制器调用saveTaskResult()时,记录都会正确保存到数据库中.
@Service
public class DemoService {
@Autowired
private TaskResultDao taskResultDao;
@Autowired
private TaskScheduler scheduler;
public void scheduleNewTask() {
scheduler.scheduleWithFixedDelay(new Runnable() {
public void run() {
// do some action here
saveTaskResult(new TaskResult("result"));
}
}, 1000L);
}
@Transactional
public void saveTaskResult(TaskResult result) {
System.out.println("saving task result");
taskResultDao.persist(result);
}
}
Run Code Online (Sandbox Code Playgroud) 我知道这 implements Runnable比extends Thread Java线程更受欢迎,因为它允许我们在需要时扩展其他类.但如果是这样的话,它extends Thread也有自己的优势implements Runnable,如果是的话,这些优势是什么?
runnable ×10
java ×8
android ×4
asynchronous ×1
java-threads ×1
scala ×1
service ×1
spring ×1
timertask ×1