我试图理解线程逻辑。如您所知,Web上的所有文档都提供了两种使用线程的方法。
扩展Thread类
实施Runnable接口
但我不明白一点。如果我能够创建Runnable方法,为什么还要使用其中一个?因为在大多数情况下,使方法可运行是最终解决方案,我认为。
这是我尝试的简单示例:
public class ThreadTest extends JFrame {
JButton btn1 = new JButton("1asd");
JButton btn2 = new JButton("2asd");
ThreadTest() {
btn1.setLocation(0, 0);
btn2.setLocation(380, 380);
add(btn1);
add(btn2);
setLayout(new FlowLayout(FlowLayout.CENTER));
setLocationRelativeTo(null);
setVisible(true);
setSize(400, 400);
}
Runnable sagaCek = new Runnable() {
@Override
public synchronized void run() {
try {
while (true) {
btn1.setLocation((int) (btn1.getLocation().getX() + 1), 0);
Thread.sleep(1000);
System.out.println("saga cekiyor");
}
} catch (InterruptedException ex) {
Logger.getLogger(ThreadTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
Runnable yukariCek = new Runnable() {
@Override
public synchronized void run() {
try {
while (true) {
btn2.setLocation(0, (int) (btn2.getLocation().getY() + 1));
Thread.sleep(1000);
System.out.println("yukari cekiyor");
}
} catch (InterruptedException ex) {
Logger.getLogger(ThreadTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
public static void main(String[] args) {
ThreadTest tt = new ThreadTest();
Thread t1 = new Thread(tt.sagaCek);
Thread t2 = new Thread(tt.yukariCek);
t1.start();
t2.start();
}
}
如果我能够将类的方法划分为Threads,为什么我需要创建类Runnable并从类构造函数调用Thread。如果我能对Threads提出进一步的建议,我将非常感激。
答案 0 :(得分:1)
您创建的内容不是“Runnable
方法”。 sagaCek
和yukariCek
是实现Runnable
的相应匿名类的实例。
您可以致电sagaCek.getClass()
进行检查,然后观察ThreadTest$1.class
。所以实际上你正在使用创建线程的第二种方法。
答案 1 :(得分:0)
使用run方法的Runnable只是一段代码。
您可以通过调用runnable.run()直接执行它,但这样做,代码将在当前线程中按顺序执行。
您还可以通过创建新线程(runnable)和启动线程等线程,将这段代码执行到另一个并发线程中。
答案 2 :(得分:0)
嗯,讨论不是关于“终极解决方案”,而是关于正确的设计。
如果要创建一个经过验证的线程,则从Thread
类继承
当对象可以并行运行但不直接运行时,可以实现Runnable
。
就是这样,没有“更好”的解决方案或最终解决方案。
JFrame
不是线程,也不是并行运行的东西。这是一个图形对象。因此(在我看来),JFrame
不适合作为costimzed线程而不适合作为runnable对象。它适合作为runnable对象的成员,如果这对给定的场景有任何意义。
PS。
在您的示例中, 实施Runnable
,就像匿名类一样。