我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方法中,为什么?更重要的是,安全点何处才能发生?
当我在VM中运行Swing应用程序时,我正在观察Java 8(几个版本,特别是1.8.0_111)的一些奇怪行为.VM是在VMware中运行的Windows 10计算机,我远程桌面插入.我没有尝试使用实际的桌面而不是虚拟机来执行此操作,但我计划尽快删除额外的故障点.
我已经设法用这个最小的程序重现它:
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
for (int i = 0; i < 3; i++) {
JPanel subpanel = new JPanel();
JComboBox<?> box = new JComboBox<>();
subpanel.add(box);
panel.add(subpanel);
}
frame.add(panel);
frame.pack();
frame.setVisible(true);
Timer timer = new Timer(1000, e -> {
frame.repaint();
});
timer.setRepeats(true);
timer.start();
});
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我只是正常启动,它会重新绘制,完全没有问题,只有一个带有3个空组合框的框架,正如预期的那样.如果我最小化RDP会话窗口,则会出现此问题.如果发生这种情况(并且框架没有图标化),那么Swing会开始吃掉不健康的CPU,直到我再次打开RDP窗口.
我已经尝试进一步最小化代码示例,但是将组合框计数减少到2,删除subpanel或设置单火定时器(而不是重复,即使在RDP最小化时重绘会发生)都可以防止错误发生.
这是CPU利用率图:http:
//i67.tinypic.com/23rwglx.png
我试过在这些尖峰期间对应用程序进行分析,试图看看到底发生了什么.以下是JVisualVM中的分析器的结果:http://i68.tinypic.com/apdwed.png
和采样器(删除包过滤器后):http:
//i67.tinypic.com/2071735.png
我无法轻易看到可能会占用CPU的东西 …
我遇到了一些多线程Java程序的问题,并将其简化为一个非常简单的例子 - 我的困惑仍然不少!
它的示例程序如下所示.那么这是做什么(或者打算做什么)?好吧,main()函数从一个简单的线程开始,基于一个静态的内部类Runnable.这个Runnable包含两个嵌套循环,它们对局部变量"z"进行简单计算,总计10 ^ 12次迭代(10 ^ 6*10 ^ 6),之后它将打印出结果并退出.产生这个工作线程后,主线程进入一个自己的循环,它将字符串"Z"打印到控制台,之后它休眠(使用Thread.sleep())1秒钟,然后反复重复.
所以运行这个程序,我希望它在计算线程正在完成它的工作时每1秒打印一次"Z".
然而,事实上发生的是计算线程启动,主线程显示第一个"Z",但没有任何反应.它似乎挂在Thread.sleep调用中,无论是无限的还是至少很多,比请求的1000毫秒长得多.
请注意,这是在具有多线程的快速四核机器上,因此同时运行线程应该没有问题.其他核心在Windows任务管理器中显示为空闲.此外,即使在单核系统上,我也希望操作系统定期抢占计算线程,以便允许主线程打印字符串.此外,线程之间没有共享变量或锁定,因此它们不应该相互阻塞.
更奇怪的是,它似乎对行为至关重要,Runnable中有两个嵌套循环.只需一个循环,迭代次数相同,一切都按预期工作.
我已经使用Java 1.8.0_73在Windows 10 64位上对此进行了测试.
有人可以解释这种行为吗?
public class Calculate {
static class Calc implements Runnable
{
@Override
public void run() {
int z = 1;
for(int i = 0; i < 1000000; i++) {
for(int j = 0; j < 1000000; j++) {
z = 3*z + 1;
}
}
System.out.println("Result: " + z);
}
}
public static void main(String[] args) throws Exception
{
Thread t = …Run Code Online (Sandbox Code Playgroud) 我正在开发一个项目,我想以编程方式关闭一个通用的JOptionPane(通过不点击任何按钮).当计时器到期时,我想关闭任何可能打开的可能的JOptionPane并将用户踢回我的程序的登录屏幕.我可以很好地踢回用户,但除非我实际点击它上面的按钮,否则JOptionPane仍然存在.
我看过许多没有运气的网站.似乎不可能在JOptionPane的"Red X"上调用doClick()方法,并且使用JOptionpane.getRootFrame().dispose()不起作用.
我有一个秋千 JTable使用大量数据动态更新 - 不断添加新行,并在几分钟内添加1000-2000行.我已经注册了一个Listener来响应使用的单行选择事件来执行一些工作人员.我已经使用Observer模式进行Swing数据绑定,并且表的模型由WritableList实现支持.因此,新项目将从其自己的Realm添加到表中.并且从SWT UI线程添加了Listener.问题是,当新行添加到表时,它不会立即响应用户行选择事件.只有在停止更新表格模型时,表格才会响应用户选择 - 有时会延迟30-60秒.请帮助我解释为什么我的表模型在深度更新时不会立即响应用户选择,以及如何克服此限制.
我一直在浏览SO和谷歌一段时间来回答这个问题,但我似乎无法找到一个真正有用的.我将从头开始:
我创建了一个Java类,其中包含一个在后台运行批处理文件的方法(命令窗口不会出现).该程序运行良好,但对最终用户来说会有点混乱,因为批处理文件需要一段时间才能完成 - 用户不知道程序是否仍在运行.批处理脚本完成执行后,会出现一个消息对话框,说明它已完成,但是在运行方法和对话框出现之间的一段时间内,看起来好像程序什么也没做.
所以这是我的问题:我非常希望显示一个带有文本区域的新框架,该文本区域显示批处理文件的输出.但是,据我所知,如果不创建临时文件,写入文件,从中读取文件等,这很难做到.如果可能的话,我宁愿避免这样做.因此,我已经决定在进程运行时显示不确定的JProgressBar可能会更好,并在进程完成时关闭它.不幸的是,我不认为Swing可以处理这个问题,因为它需要同时运行多个进程.我听说过SwingWorker,但我不确定在这种情况下如何使用它.我有以下SSCCE,它可以工作,但没有实现进度条.
public myClass(){
public static void main(String[] args){
String[] commands = {"cmd.exe", "/C", "C:\\users\\....\\myBat.bat"};
Process p = Runtime.getRuntime().exec(commands);
p.waitFor()
JOptionPane.showMessageDialog(null, "Process finished!");
}
}
Run Code Online (Sandbox Code Playgroud)
当p.waitFor()等待进程时,屏幕上没有任何内容.我只是希望向用户显示进程仍在运行的内容.思考?谢谢!
我有一个没有主动渲染的JFrame,一个标准的基本Swing应用程序,我需要在单击一个按钮时启动另一个JFrame.第二JFrame的使用Swing的BufferStrategy中积极渲染,以及运行在它自己的独立 - 但是,当我把它从其他的JFrame的actionPerformed都JFrames冻结.
我知道使用Swing来完成这种行为是很复杂的 - 我怎么能绕过它们?
我正在尝试使用Swing创建一个测试互斥算法的平台.我的目的是在GUI中显示它们之间发送的服务器和消息.我还想显示一个关键部分,显示当前正在访问它的服务器.我正在使用一个执行SwingWorker线程的线程池来部署加载用户选择的互斥算法的服务器.
程序按预期运行,直到我尝试实现消息显示.为了显示每条消息的箭头,我扩展了SwingWorker,UIArrowThread,以添加一个从源服务器向目标绘制箭头的JLabel.在删除JLabel之前,此线程等待1秒.当我明确地创建一个或多个这些消息时,这似乎工作正常(我还创建了一个可以创建特定消息的测试平台).
当我尝试将此SwingWorker线程集成到程序中时,问题就出现了.启动算法时,每个服务器都会尝试访问关键部分并将其请求发送到每个其他服务器.这应该调用UIArrowThread,但似乎只有一些服务器实际上创建了该线程.
public void sendMsg(int destId, Object ... objects) {
comm.sendMsg(destId, objects);
try{
UIArrowThread a = new UIArrowThread(AlgorithmSimulatorUI.jlp,
objects[0].toString(),
comm.getMyId(),
destId);
AlgorithmSimulatorUI.threadPool.execute(a);
} catch (Exception exc){
System.err.println(exc);
}
}
Run Code Online (Sandbox Code Playgroud)
有些服务器似乎在实例化UIArrowThread之前就停止执行,最终导致死锁.任何使它通过该点的服务器都能正常工作,GUI显示应该是正常的.我在调用UIArrowThread之前和它的构造函数中测试了日志.看起来停止执行的线程永远不会在构造函数中进行日志调用.我很难理解为什么会发生这种情况.
public class UIArrowThread extends SwingWorker<Integer, String>{
JLayeredPane jlp;
String type;
int source;
int target;
Point start;
Point end;
Point[] points;
int quadrant;
public UIArrowThread(JLayeredPane jlp, String msg_type, int source,
int target){
this.jlp = jlp;
this.type = msg_type;
this.source = source;
this.target = target;
this.points = getPoints();
this.start = points[0]; …Run Code Online (Sandbox Code Playgroud)