java中的一些并发设计
我需要从服务器上检索一张巨大的图片,但是服务器不能这样做,因为图像太大了。我可以给出“坐标”,这样我就可以检索图片的一小部分。因此,我将图片分成100块,然后将10块添加到一行,然后添加每行。如果我按顺序做,效果会很好。现在我下载10个互动程序->将它们追加到一行->下载下一个10个互动程序->将它们追加到一行->将第二行追加到第一行->下载下一个10个互动程序等(简化):java中的一些并发设计,java,multithreading,concurrency,runnable,java-threads,Java,Multithreading,Concurrency,Runnable,Java Threads,我需要从服务器上检索一张巨大的图片,但是服务器不能这样做,因为图像太大了。我可以给出“坐标”,这样我就可以检索图片的一小部分。因此,我将图片分成100块,然后将10块添加到一行,然后添加每行。如果我按顺序做,效果会很好。现在我下载10个互动程序->将它们追加到一行->下载下一个10个互动程序->将它们追加到一行->将第二行追加到第一行->下载下一个10个互动程序等(简化): publicstaticvoid下载wholeimage(){ int xcoord=0; int ycoord=0; /
publicstaticvoid下载wholeimage(){
int xcoord=0;
int ycoord=0;
//每行的外部循环
对于(int i=0;i,看起来您希望在添加互动程序时异步下载其他互动程序
因此,您的答案似乎可以在此处找到:
注意:您不需要等待。只需让一个进程异步完成,而另一个进程正在运行
编辑:您还可以使用同步块来定义,在每次成功下载后,应执行特定的附加操作。其中一种可能是创建主线程,该线程将运行N个下载线程。每个下载线程将从服务器获取磁贴,然后可以交换大图片的片段至于交换,它可能可以由多个线程同时完成,只要每个线程都在全局中自己的部分上运行,这样它们就不会“冲突”。想象一个数组,其中一个线程的索引为0到X,另一个为X+1到数组的末尾。要使它工作,你必须事先知道全局的大小并初始化它。但我认为你已经这样做了。主线程只会等待所有小线程结束,这意味着任务已经完成。你可以这样做如下所示:为每个下载操作创建一个新线程,其中下载发生在run()方法中。每个线程然后等待下一次下载使用join()完成,并附加互动程序
可以使用类似的方法下载和附加每一行
public class Download extends Thread {
public static void main(String[] args) throws InterruptedException {
Download[] download = new Download[10];
for (int i = 0; i < 10; i++) {
download[i] = (new Download(i));
download[i].start();
}
for(int i = 0; i < 10; i++) {
(download[i]).join();
append(i);
}
}
int val;
Download(int val) {
this.val = val;
}
@Override
public void run() {
System.out.println("Downloading tile " + val);
}
公共类下载扩展线程{
公共静态void main(字符串[]args)引发InterruptedException{
下载[]下载=新下载[10];
对于(int i=0;i<10;i++){
下载[i]=(新下载(i));
下载[i].start();
}
对于(int i=0;i<10;i++){
(下载[i]).join();
附加(i);
}
}
int-val;
下载(int-val){
this.val=val;
}
@凌驾
公开募捐{
System.out.println(“下载磁砖”+val);
}
编辑
如果您希望实现Runnable,语法如下
public class Download implements Runnable {
...
Thread[] download = new Thread[10];
for (int i = 0; i < 10; i++) {
download[i] = new Thread(new Download(i));
公共类下载实现可运行{
...
线程[]下载=新线程[10];
对于(int i=0;i<10;i++){
下载[i]=新线程(新下载(i));
这与第一个示例的工作方式完全相同,因此选择扩展线程还是实现Runnable是一个品味问题。在我看来,您仍然需要按顺序下载行,并且在每行中确保在移动到下一行之前下载所有10个tile
看看java.util.concurrent
包,特别是
这是一段代码片段。注意:它可能无法正确编译,但给出了一个想法
public static void main(String[] args) throws InterruptedException {
CountDownLatch countLatch = new CountDownLatch(10);
ExecutorService threadPool = Executors.newFixedThreadPool(10);
ArrayList<SampleImageDownload> list = new ArrayList<SampleImageDownload>();
int row =1;
while (row <=10) {
int tileno = 1;
while(tileno <=10) {
SampleImageDownload sample = new SampleImageDownload(countLatch, tileno);
list.add(sample);
threadPool.submit(sample);
tileno++;
}
row++;
countLatch.await(); // wait for all 10 tiles to download.
//apendline
}
}
class SampleImageDownload implements Runnable {
int tileno;
private CountDownLatch countLatch = null;
BufferedImage tile = null;
public SampleImageDownload(CountDownLatch countLatch, int tileno) {
super();
this.countLatch = countLatch;
this.tileno = tileno;
}
@Override
public void run() {
// download and removeBlacktile
// tile is ready
countLatch.countDown();
}
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
CountDownLatch countLatch=新的CountDownLatch(10);
ExecutorService线程池=Executors.newFixedThreadPool(10);
ArrayList=新建ArrayList();
int行=1;
虽然(row感谢您的回答,但您所说的“用瓷砖交换大画面的片段”是什么意思?很酷,这也适用于implements runnable
而不是extends thread
?第二个for循环是在第一个循环的第一次迭代完成后开始的吗?是的,implements runnablee> 以相同的方式使用稍微不同的语法。第一个循环调度10个线程,但不等待它们启动。main()方法将立即转到第二个循环并等待下载完成。我不确定我是否理解这一点,但是:您使用的是一个线程,但一次只使用一个线程?因此没有并发性,需要的时间与没有线程(如我上面的问题)或Executors.newFixedThreadPool(10)时一样多
创建一个线程池,我们将每个磁贴下载提交到此池。10个线程同时运行。
public static void main(String[] args) throws InterruptedException {
CountDownLatch countLatch = new CountDownLatch(10);
ExecutorService threadPool = Executors.newFixedThreadPool(10);
ArrayList<SampleImageDownload> list = new ArrayList<SampleImageDownload>();
int row =1;
while (row <=10) {
int tileno = 1;
while(tileno <=10) {
SampleImageDownload sample = new SampleImageDownload(countLatch, tileno);
list.add(sample);
threadPool.submit(sample);
tileno++;
}
row++;
countLatch.await(); // wait for all 10 tiles to download.
//apendline
}
}
class SampleImageDownload implements Runnable {
int tileno;
private CountDownLatch countLatch = null;
BufferedImage tile = null;
public SampleImageDownload(CountDownLatch countLatch, int tileno) {
super();
this.countLatch = countLatch;
this.tileno = tileno;
}
@Override
public void run() {
// download and removeBlacktile
// tile is ready
countLatch.countDown();
}
}