- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我需要加快悬停在一堆矩形上的光标响应速度。随着矩形数量(或复杂性)的增加,迭代矩形的直接线性算法开始恶化。
这个超链接展示了一个线性搜索模型(记得添加break关键字!!!)linear approach
为了清楚地表明我的意思,下面是一个 JPanel 的代码,它有两组矩形。第一组是 y 轴上的矩形列表,第二组是 x 轴上的矩形列表。
请记住,我的解决方案是我能想到的最好的解决方案,即使用两个线程来并发迭代;每个列表一个线程,一个用于 x 轴,另一个用于 y 轴。我放弃的次优解决方案(代码未显示)是循环内有一个循环。一个循环专用于 x 轴矩形,另一个循环专用于 y 轴矩形。这一点,我认为通过 contains() 方法搜索 y 轴矩形(假设内部循环专用于 y 轴矩形)通过首先循环所有 x 轴矩形而施加了过度的开销。
为了改进线性模型,我想到了这种线程方法来同时参与工作线程。
顺便说一句,我是一个java新手,尤其是多线程方面。
问题:一个线程似乎会干扰另一个线程的性能。下面的算法是由两个扩展 Thread 的包装类实现的,它们都有迭代矩形的方法。如果另一个线程被注释掉,它们都可以很好地工作,即每个单独和单独都可以很好地工作,但是当两者同时启动时,其中一个会导致性能下降。
如果我 join() 一个线程,这不是会恢复到线性模型,随着矩形复杂性的增加,这种搜索算法是很糟糕的吗?
(复杂性不仅意味着水平和垂直,还意味着对角线等矩形)?
public class FlyingSaucer extends JPanel {
Rectangle2D rec;
Rectangle2D rec1;
List<Rectangle2D> recList;
List<Rectangle2D> recList2;
Rectangle2D.Double mouseBoxx;
int f = 10;
int g = 0;
int s = 10;
int y = 5;
int z = 500;
public FlyingSaucer(){
//FlyingSaucer needs to quickly identify specific points over given areas
//enclosed in rectangles.They use a 'divide and conquer' approach where
//different types of rectangles are first identified and a worker thread
//assigned to each category
mouseBoxx = new Rectangle.Double();
recList = new ArrayList<>();
recList2 = new ArrayList<>();
for(int i = 0; i < 15; i++){
rec = new Rectangle2D.Double(2+f,10+g,5,1000);
f +=50;
recList.add(rec);
}
f = 10;
for(int i = 0; i < 20; i++){
rec1 = new Rectangle2D.Double(2+y,10+s,1000,5);
s +=35;
recList2.add(rec1);
}
s = 10;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
FlyingSaucer fs = new FlyingSaucer();
Laser laser = new Laser(fs);
fs.addMouseMotionListener(laser);
fs.addMouseListener(laser);
frame.getContentPane().add(fs);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700,700);
frame.setVisible(true);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D)g).setColor(Color.RED);
int a = 10;
int b = 10;
for(int i = 0;i < recList.size();i++){
((Graphics2D)g).draw(recList.get(i));
}
for(int i = 0;i < recList2.size();i++){
((Graphics2D)g).draw(recList2.get(i));
}
}
}
class Laser implements MouseListener,MouseMotionListener{
Rectangle2D.Double mouseBox;
Rectangle2D.Double recx;
Rectangle2D.Double recy;
FlyingSaucer fs;
public Laser(FlyingSaucer fs){
this.fs = fs;
}
@Override public void mouseClicked (MouseEvent e) { }
@Override public void mousePressed (MouseEvent e) { }
@Override public void mouseReleased(MouseEvent e) { }
@Override public void mouseEntered (MouseEvent e) { }
@Override public void mouseExited (MouseEvent e) { }
@Override public void mouseDragged (MouseEvent e) { }
@Override
public void mouseMoved(MouseEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
double x = e.getX();
double y = e.getY();
mouseBox = fs.mouseBoxx;
mouseBox = new Rectangle2D.Double(x-5,y-5,10,10);
Graphics g = fs.getGraphics();
((Graphics2D)g).setColor(Color.BLACK);
((Graphics2D)g).draw(mouseBox);
//thread one for horizontal rectangles
HorizontalBuffer hb = new HorizontalBuffer(fs,e);
hb.start();
//thread two for vertical rectangles
VerticalBuffer vb = new VerticalBuffer(fs,e);
vb.start();
fs.repaint();
g.dispose();
}});
}
class HorizontalBuffer extends Thread{
FlyingSaucer fs;
MouseEvent e;
List<Rectangle2D> recX;
public HorizontalBuffer(FlyingSaucer fs,MouseEvent e){
this.fs = fs;
this.e = e;
}
public void run() {
recX = fs.recList;
Iterator <Rectangle2D> recs = recX.iterator();
int v = 1;
while(recs.hasNext()){
recx = (Rectangle2D.Double) recs.next();
if(recx.contains(e.getPoint())){
System.out.println("X rectangle detected.."+v);
fs.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
break;
}
else {fs.setCursor(Cursor.getDefaultCursor());}
v++;
}
}
}
class VerticalBuffer extends Thread{
FlyingSaucer fs;
MouseEvent e;
//List<Rectangle2D> recX;
List<Rectangle2D> recY;
public VerticalBuffer(FlyingSaucer fs,MouseEvent e){
this.fs = fs;
this.e = e;
}
public void run(){
recY = fs.recList2;
Iterator <Rectangle2D> recs = recY.iterator();
int v = 1;
while(recs.hasNext()){
recy = (Rectangle2D.Double) recs.next();
if(recy.contains(e.getPoint())){
System.out.println("Y rectangle detected.."+v);
fs.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
break;
}
else {fs.setCursor(Cursor.getDefaultCursor());}
v++;
}
}
}
}
最佳答案
您的 FlyingSaucer 类不是线程安全的,但您正在从两个不同的线程(HorizontalBuffer 和 VerticalBuffer)访问它。这可能会导致问题:例如,当 HorizontalBuffer 尝试获取 FlyingSaucer reclist
时,它可能会获取 null 并引发异常。由于不同步访问也可能出现其他问题。这不是最容易调试的事情:例如,除非您观察控制台,否则您不会知道异常,因为一个线程中的异常不会终止多线程程序。
您可以通过正确同步对 FlyingSaucer 的访问使 FlyingSaucer 线程安全来解决此特定的访问同步问题。但也可能存在其他问题;让多线程应用程序正常工作并不简单,对于 Java 新手来说可能不是最好的方法,正如您所说的那样。
正如其他人在评论中指出的那样,最好的解决方案可能不是多线程。我建议用您的单线程解决方案发布一个新问题,并询问如何加快速度。您可以在该问题中提到多线程,但我建议也对其他解决方案持开放态度。
关于Java Swing : Improving cursor response using Threads,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46283798/
我有一个包含以下内容的简单服务: import { Injectable } from '@angular/core'; import { Http, Response } from '@angula
在我的 Angular-12 应用程序中,我在服务中有以下代码: constructor(private http: HttpClient, private router: Router) {
我是android领域的新手,我想从响应json数组访问每个结果元素,但我无法做到这一点,我试图获取每个元素,但我只得到一个值“rohit1”是第一个元素。请帮助我。 我是 rohit parmar,
我正在用 java 编写 RESTful 服务,但是当我尝试使用 Resource 类时,显示以下错误:类型 Response.Response 构建器不可见。我不明白问题可能是什么,因为我已经导入了
在 Spring 应用程序中,我正在调用第三方服务,我正在发送 XML 请求并获取 XML 响应,当无法将该响应解析为 Java 对象时,我正确地获得了 XML 响应,我收到以下错误: org.spr
我正在发布一个页面 URL 例如 mysite.com/disclaimer/someinfo 此页面显示协议(protocol),如果用户单击同意按钮,则 PDF 文件将作为附件流式传输。 这样做的
我是 Camel 的新手。我一直在尝试将数据(文件中的 Json)提交到网络服务。这是我的代码: public static void main(String args[]) throws E
我有一个 HTTP 执行器类: Future future = service.apply(request).toJavaFuture(); 现在我想删除 ? extends其中的一部分,因为我不想让
我想将我所有的 http header 响应设置为这样的: response.headers["X-Frame-Options"] = "SAMEORIGIN" 我检查了this question ,
我们有两个 channel ,分别是 channelA 和 channelB。 在 channel A中我们有两个目的地 一个。第一个目的地将使用 XML 数据作为输入调用 channelB,并从 c
以下有什么区别 response.status(200).send('Hello World!'); 和这个 response.writeHead(200, {'content-type':'appl
我试图让Foundation在iPhone的浏览器上响应。我已经在手机上尝试过Safari和Chrome,它们都显示了 table 面布局。 但是,在 table 面上,如果缩小浏览器窗口,则会看到布
您好,当我在云代码中运行此作业时,我收到一条错误日志:Failed with: success/error was not called. 定义功能运行良好,但在作业日志中我有此错误日志。请协助我解决
我正在使用ozeki ng短信网关。我无法将任何短信发送到任何手机。请帮助我通过网络发送短信到手机 从客户端检测到一个潜在危险的Request.Form值(textboxError =“。设置此值之后
今天我在 WordPress 中遇到了问题。当我尝试创建一个新页面并在 WordPress 管理部分上传新图像时,我尝试找出解决方案,但我没有得到它......所以经过一个小时的打磨后我得到了一个解决
我过去常常通过刷新和结束来结束对客户端的传输,如下面的代码所示。 Response.Flush(); Response.End(); 但是,Response.End() 将缓冲内容刷新到客户端让我印象
我正在编写一个在单击按钮时显示对话框窗口的函数:这里是与状态和 statusCode 相关的代码段。 if(response.status>300){
从资源清理的角度,为什么会有Response.Close()和Response.Dispose(),哪个更全面(调用另一个)? 最佳答案 在提供这两种方法的情况下,Dispose 的实现应该调用 Cl
在我注意到我的代码可能在以经典模式设置的服务器上运行之前,我一直在使用 Response.Header.Add()。在这种情况下,异常“此操作需要 IIS 集成管道模式”。被提出。 我切换到 Resp
Response.End() 生成 ThreadAbortException。 使用 HttpContext.Current.ApplicationInstance.CompleteRequest 代
我是一名优秀的程序员,十分优秀!