L'algoritmo non è immediato da comprendere, ma se ho capito bene...

codice:
for (int j = 0; j < matrice2[0].length; j++)
lo trasformerei in

codice:
for (int j = 0; j < matrice2[0].length; j+=2)
eliminando il j++ alla fine (stessa cosa per la variabile "y").

codice:
for (int x = 0; x < matrice2.length - 1; x++)
puoi modificarlo in

codice:
for (int x = i + 1; x < matrice2.length; x++)
visto che, se una riga è unica rispetto a tutte quelle che la seguono, sarà vero anche il viceversa.

C'è una parentesi tonda di troppo in

codice:
if (i != x && j != y && matrice2[i][j] == matrice2[x][y]))
In ogni caso non mi torna la parte centrale del codice... a occhio io la farei così (prova a pensarci e dimmi cosa ne pensi)

codice:
if (matrice2[i][j] == matrice2[x][y] && matrice2[i][j + 1] == matrice2[x][j + 1])
{
  return false;
}
Eliminerei inoltre la variabile "controllo": se raggiungi la fine del ciclo significa che non ci sono coppie duplicate e quindi puoi fare un return true