理解同步并实现队列

3

我正在开发一个Android应用程序,需要进行多个网络请求。我希望所有这些请求按照它们到达的顺序依次处理,我的下面的代码可以实现吗?

根据我的阅读和理解,synchronized关键字的作用是,在我启动的所有线程中,只有一个线程可以进入以下任何一个方法。例如,如果用户在一个线程中尝试postPhoto,然后立即在另一个线程中尝试getData,则getData线程将不得不等待postPhoto线程完成后才开始获取数据。由于我所有的网络请求都通过这个类并且所有的方法都是同步的,那么它们基本上就是排队的,对吗?

public class Controller {

public synchronized static String getData(String url, String limit) { ... }

public synchronized static String postPhoto(String filepath, int server_id) { ... }

public synchronized static InputStream getPhoto(String thumbnailPath) { ... }

public synchronized static String createIncident(String name, String description) { ... }

public synchronized static String updatePerson() { ... }

synchronized static boolean verifyConnection(String response) { ... }
}

编辑:
我可能应该提到,尽管上述某些方法被称为createIncident或updatePerson,但它们都只是发起http请求。所有这些方法内部的代码基本相同,除了一些重要的小变化。在我的代码的其他部分中,我会启动线程来调用这些方法,这就是我问的部分。因为这些线程在调用这些方法,所以B线程调用getData时必须等待A线程完成postPhoto的一部分。


1
大多数队列背后的想法是允许生产者和消费者并发工作。在这种情况下,您将序列化您的请求,但是当“消费者”忙碌时,“生产者”将会阻塞。 - Peter Lawrey
只是为了澄清@Peter所说的:你的代码基本上不是多线程的,这可能不是你想要的。它确实是安全同步的,但是过于同步以至于你只能在多核硬件上获得与单核相对应的性能。 - toto2
我要澄清一下。我认为在原始问题中漏掉了一些重要信息。 - joshkendrick
阅读您的编辑后,我发现您的过度同步问题比我想象的还要严重。当一个方法进行http请求时,它会持有Controller.class的锁,因此在等待回复期间,其他方法无法运行...这可能需要很长时间。 - toto2
2个回答

1

是的,你说得对。使用 synchronizedstatic 的组合可以保证你想要的。


1

这也取决于你的实现方式。 你的控制器是单例还是每个线程一个实例? 你的方法使用共享对象吗?

如果是单例且方法共享对象,则即使按顺序调用,也不能保证thread1在运行postPhoto后立即运行getData。另一个线程可能会插入并开始运行这两个方法。

请注意,synchronized关键字锁定类本身,因此任何时候只会有一个方法正在执行。不会同时运行2个同步方法。


所有的方法都是静态的,所以它是否是单例并不重要。 - toto2
是的,我们看到的部分都是静态的,但也可能有一些实例方法,我们没有看到整个代码。 - fmucar
是的,它不是单例模式,所有方法都是静态的。你回答的最后一部分是我需要的。由于它们是静态的,并且在类上同步锁定,因此任何时候只有一个方法会执行。我知道顺序不会被强制执行,但我可以接受这一点。只要一次执行一个就可以了。 - joshkendrick
如果这正是您要寻找的,那就很好了。我想也许您还有其他方法,而不仅仅是类中的静态方法。 - fmucar
@Josh 顺便说一下,由于你只有静态方法,你应该没有构造函数(private Controller() { }),并且总是调用 Controller.someStaticMethod()。我个人认为在Java或任何语言中不应允许在实例上调用静态方法(constroller1.someStaticMethod();)。 - toto2
是的,那就是我的做法。没有构造函数,总是调用 Controller.whatever。不过还是谢谢你的建议。这真的很有帮助,节省了我很多时间! - joshkendrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接