Java 用于打印矩阵(二维数组)的线程同步

Java threads synchronization for printing a matrix (2d array)

您好,我正在尝试打印一个矩阵并将这项工作分配给不同的线程。

例如,在下面的代码中,我尝试执行逻辑并且它在 1 个线程中工作正常。

对于多线程,我认为我需要以某种方式同步 startend 以便每个线程获得不同的值。

我希望不同的线程打印该矩阵的不同行(取决于线程数)(顺序无关紧要),但每个线程都需要处理唯一的行.

知道如何做到这一点吗?

import javax.swing.plaf.TableHeaderUI;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Mythread {
    int[][] matrix;
    public Mythread(int nr){
        matrix = new int[nr][nr];
        for(int i = 0; i <nr; i++){
            for(int j = 0; j < nr; j++)
                matrix[i][j] = i;
        }
    }

    public void printMatrix(int start, int end){
        System.out.println("Start = " +start + ";thread"+Thread.currentThread().getId());
        System.out.println("End = " +end+ ";thread"+Thread.currentThread().getId());
        for(int i = start; i <end; i++){
            for(int j = 0; j < 4; j++) {
                System.out.print(matrix[i][j] + "<->");
            }
            System.out.println();
        }
    }

    public void testRun() throws InterruptedException {
        ExecutorService ex = Executors.newFixedThreadPool(1);
        for(int i=0 ; i < 4; i++) {
                final int start = i;
                final int end = i + 1;
                ex.execute(new Runnable() {
                    @Override
                    public void run() {
                        printMatrix(start, end);
                    }
                });
        }
        ex.shutdown();
        ex.awaitTermination(1, TimeUnit.MINUTES);
        System.out.println("DONE");

        /*
        works for nThreads = 1 -> for Thread Pool
        Start = 0;thread14
        End = 1;thread14
        0<->0<->0<->0<->
        Start = 1;thread14
        End = 2;thread14
        1<->1<->1<->1<->
        Start = 2;thread14
        End = 3;thread14
        2<->2<->2<->2<->
        Start = 3;thread14
        End = 4;thread14
        3<->3<->3<->3<->
        DONE
         */


    }



    public static void main(String[] args) throws InterruptedException {
        Mythread a = new Mythread(4);
        a.testRun();
    }
}

这里有一个简单的方法可以实现您的目标,即使用多个线程以无特定顺序打印二维整数数组的行:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class ConcurrentMatrixPrint {
    private int[][] matrix;
    public ConcurrentMatrixPrint(int nr){
        matrix = new int[nr][nr];
        for(int i = 0; i <nr; i++){
            for(int j = 0; j < nr; j++)
                matrix[i][j] = i;
        }
    }

    public void printRow(int row){
        //Creates a builder and initializes with the thread id and a tab
        StringBuilder sb = new StringBuilder();
        sb.append(Thread.currentThread().getId());
        sb.append("\t");

        //Loop through columns in the current row
        for(int i = 0; i < matrix[row].length; i++){
            //Add the data in the current row and column to the builder
            sb.append(matrix[row][i]);
            //This just makes the output a little nicer, only adds comma if there
            //  is another item to print so there is no trailing comma at the end.
            if(i+1 < matrix[row].length){
                sb.append(",");
            }
        }
        //Print the resulting comma separated string
        System.out.println(sb);
    }

    public void testRun() throws InterruptedException {
        //Use an atomic integer to prevent memory consistency issues
        AtomicInteger rowIndex = new AtomicInteger(0);
        ExecutorService ex = Executors.newFixedThreadPool(4);
        for(int i=0 ; i < matrix.length; i++) {
                ex.execute(new Runnable() {
                    @Override
                    public void run() {
                        //Each thread will print a row based on the value
                        // of the atomic integer and will also increment
                        // that integer.
                        printRow(rowIndex.getAndIncrement());
                    }
                });
        }
        ex.shutdown();
        ex.awaitTermination(1, TimeUnit.MINUTES);
        System.out.println("DONE");
    }

    public static void main(String[] args) throws InterruptedException {
        ConcurrentMatrixPrint a = new ConcurrentMatrixPrint(8);
        a.testRun();
    }
}

我在代码中添加了注释,但基本上线程都共享一个整数索引,该索引是原子的,并随着每个给执行程序的新任务而递增。

请注意,输出显示负责生成文本行作为打印的第一个值的线程 ID。所以在下面的示例输出中,您可以看到线程 12 打印了第一行,然后线程 14 打印了下一行,依此类推。

这是一些示例输出:

12  1,1,1,1,1,1,1,1
14  3,3,3,3,3,3,3,3
11  0,0,0,0,0,0,0,0
13  2,2,2,2,2,2,2,2
11  6,6,6,6,6,6,6,6
14  5,5,5,5,5,5,5,5
12  4,4,4,4,4,4,4,4
13  7,7,7,7,7,7,7,7
DONE

希望对您有所帮助!