我yield()对Java 中方法的使用有点困惑,特别是在下面的示例代码中.我还读过yield()'用于防止执行线程'.
我的问题是:
我相信下面的代码在使用yield()和不使用时都会产生相同的输出.它是否正确?
事实上,什么是主要用途yield()?
在哪些方面与方法yield()不同?join()interrupt()
代码示例:
public class MyRunnable implements Runnable {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
for(int i=0; i<5; i++) {
System.out.println("Inside main");
}
}
public void run() {
for(int i=0; i<5; i++) {
System.out.println("Inside run");
Thread.yield();
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用和不使用上面的代码我获得相同的输出yield():
Inside main
Inside main
Inside main
Inside main
Inside main
Inside run
Inside run
Inside run
Inside …Run Code Online (Sandbox Code Playgroud) 在处理我的Java应用程序时,我有一个简单的多线程案例(一个异步资源加载器线程和一个主线程等待加载器完成,用进度更新UI),我想通过调用来解决
while( !foo.isInitialized() ) {
Thread.yield();
}
Run Code Online (Sandbox Code Playgroud)
在主线程中.我知道有更强大的解决方案; 仍然,加载器不是由我设计的,它是一个基本上只读的库(我不能简单wait(),因为我无法让它发送给我notify();也就是说,它完成后不会死),我只需要等到加载完成.
Java doc说(注意这不存在于1.6文档中,并且是由1.7个文档添加的)
使用这种方法很少是合适的.
NetBeans警告我
方法
yield()on的调用java.lang.Thread通常用于伪装同步问题,应该避免.
谷歌Codepro AnalytiX,OTOH说
Thread.yield()不应使用该方法,因为其行为在所有平台上都不一致.
我是否应该关注这些警告并尝试找到更好的解决方案(欢迎提出所有建议),还是应该将其视为"警告噪音"并抑制/忽略它们?
注意:我想到了使用sleep()(Is Thread.sleep(0)和Thread.yield()语句等效的明显可能性吗?值得一提); 仍然,如果yielding在持续睡眠中没有"奖励",为什么Java会提供它 - 那么它的实际有效用例是什么呢?
根据我的理解,Thread.yield()和Thread.sleep(0)都应该让CPU重新判断某个调度算法运行哪个线程.
不同之处是:
Thread.yield()是给其他线程的执行机会,但Thread.sleep(0)不会,它只会告诉CPU你应该重新安排执行线程,包括当前线程本身.
Thread.yield()只是一个建议,这意味着它可能根本不被接受,但Thread.sleep(0)将强制进行重新排列.
以上两个结论是否正确?
我真的很困惑:当我在eclipse中正常运行我的程序时,我的一些代码无法正常工作,但是当我使用调试模式单独运行每个步骤时,它确实工作了.
码:
public void showConnectDialog() {
ConnectDialog connectDialog = new ConnectDialog();
connectDialog.setVisible(true);
//Until here, code runs
while(! connectDialog.getConnected()) {};
//The next line does only run in debug
JOptionPane.showMessageDialog(connectDialog, "Connected", "Connected", JOptionPane.INFORMATION_MESSAGE);
}
Run Code Online (Sandbox Code Playgroud)
连接器(一旦用户在对话框中点击"连接")就启动(作为线程):
private class ServerConnector implements ActionListener, Runnable {
@Override
public void actionPerformed(ActionEvent e) {
if (! IP_field.getText().equals("")) {
if (! isConnecting) {
new Thread(new ServerConnector(), "ServerConnector").start();
}
}
else {
JOptionPane.showMessageDialog(dialog,
"Enter an IP address",
"Enter IP",
JOptionPane.WARNING_MESSAGE);
}
}
@Override
public void run() {
try {
setConnecting(true); …Run Code Online (Sandbox Code Playgroud) 我知道一个区别:
如果我们说thread.sleep(1000),那个线程1000肯定会睡几毫秒,而yield()没有这样的保证.这对于线程调度很有用,因为调用的线程yield()可以立即再次选择以便运行.
还有什么?
基本上,我正在制作一个更新玩家位置的游戏,它使用这个帖子:
@Override
public void run() {
while(true) {
System.out.println();
updatePos(x, y);
}
}
Run Code Online (Sandbox Code Playgroud)
哪个工作正常,但如果我删除System.out.println(),它就会停止运行.我不知道为什么会这样,全班如下:
public class Player extends Block implements KeyListener, Runnable {
int x;
int y;
int speed;
boolean upPressed;
boolean downPressed;
boolean rightPressed;
boolean leftPressed;
static Sprite sprite = new Sprite("grass.png");
public Player(int x, int y, int speed) {
super(x, y, sprite);
this.x = x;
this.y = y;
this.speed = speed;
Thread playerThread = new Thread(this, "Player Thread");
playerThread.start();
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() …Run Code Online (Sandbox Code Playgroud) 这是一个多线程的HelloWorld:
public class HelloWorld {
public static void main(String[] args) throws InterruptedException {
Thread myThread = new Thread() {
public void run() {
System.out.println("Hello World from new thread");
}
};
myThread.start();
Thread.yield();
System.out.println("Hello from main thread");
myThread.join();
}
}
Run Code Online (Sandbox Code Playgroud)
据我了解,之后myThread.start()会有两个线程在运行.一个是主线程,另一个是新创建的myThread.然后,在哪个线程中引用Thread.yield()?
我查了一下Java SE6 Doc
Thread.yield():使当前正在执行的线程对象暂时暂停并允许其他线程执行
但在代码中,我无法清楚地看到currently excuting thread它是什么,它看起来两个线程同时运行.
是不是更清楚地说myThread.yield()而不是Thread.yield()?有没有人有这个想法?