Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的一些并发设计_Java_Multithreading_Concurrency_Runnable_Java Threads - Fatal编程技术网

java中的一些并发设计

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; /

我需要从服务器上检索一张巨大的图片,但是服务器不能这样做,因为图像太大了。我可以给出“坐标”,这样我就可以检索图片的一小部分。因此,我将图片分成100块,然后将10块添加到一行,然后添加每行。如果我按顺序做,效果会很好。现在我下载10个互动程序->将它们追加到一行->下载下一个10个互动程序->将它们追加到一行->将第二行追加到第一行->下载下一个10个互动程序等(简化):

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();

    }

}