A cópia do código é a seguinte:
pacote com.yao;
importar java.util.concurrent.executorService;
importar java.util.concurrent.executores;
importar java.util.concurrent.future;
importar java.util.concurrent.locks.lock;
importar java.util.concurrent.locks.readwritelock;
importar java.util.concurrent.locks.reentrantlock;
importar java.util.concurrent.locks.reentrantreadwritelock;
/**
* Armários
* Um conceito importante na programação multi-threaded é bloqueio.
* Ao executar operações transacionais, o recurso compartilhado precisa ser bloqueado, o que garante que apenas um thread possa operar no recurso ao executar operações transacionais.
* Isso garante a integridade dos dados. Antes de 5.0, a função de bloqueio foi implementada pela palavra -chave sincronizada.
*/
Classe de classe pública {
/**
* Teste o uso do bloqueio. O uso do bloqueio no método pode evitar o uso da palavra -chave sincronizada.
*/
classe estática pública Locktest {
Trava de trava = new reentrantlock (); // bloqueio
valor duplo = 0d;
int addtimes = 0;
/**
* Aumentar o valor do valor.
* Portanto, o método deve ser sincronizado, a prática anterior era usar a palavra -chave sincronizada na declaração do método.
*/
public void AddValue (Double V) {
Lock.lock (); // Obtenha a trava
System.out.println ("Locktest para AddValue:" + V + ""
+ System.currenttimemillis ());
tentar {
Thread.sleep (1000);
} catch (interruptedException e) {
}
this.value += v;
this.AddTimes ++;
Lock.Unlock (); // Libere o bloqueio
}
public duplo getValue () {
retornar este.value;
}
}
public static void testlockTest () lança exceção {
LOCKTEST FINAL LOCKTEST = new LockTest ();
// Crie uma nova tarefa 1 e ligue para o método AddValue de Locktest
Runnable Task1 = new Runnable () {
public void run () {
LOCKTEST.AddValue (55,55);
}
};
// Crie nova tarefa 2 e chame o método getValue do Locktest
Runnable Task2 = new Runnable () {
public void run () {
System.out.println ("Value:" + LockTest.getValue ());
}
};
// Crie um novo serviço de execução de tarefas
ExecutorService cachedservice = executores.newcachedthreadpool ();
Futuro futuro = nulo;
// Execute a tarefa 1 três vezes ao mesmo tempo.
for (int i = 0; i <3; i ++) {
futuro = cachedservice.submit (tarefa1);
}
// Aguarde a última tarefa 1 ser executada
futuro.get ();
// execute a tarefa 2 novamente para gerar o resultado
futuro = cachedservice.submit (Task2);
// Depois de esperar a execução da Tarefa 2, feche o serviço de execução de tarefas
futuro.get ();
cachedservice.shutdownNow ();
}
/**
* O ReadWritelock possui dois bloqueios embutidos, um é o bloqueio de leitura e o outro é o bloqueio escrito.
* Vários threads podem obter bloqueios de leitura ao mesmo tempo, mas apenas um thread pode obter bloqueios escritos.
* E depois que a trava escrita está travada, nenhum fio pode obter a fechadura. Os métodos fornecidos pela ReadWritelock são:
* readlock (): retorna um bloqueio de leitura
* WRITELOCK (): Retorna um bloqueio escrito, este bloqueio é exclusivo.
* O ReadWritelockTest é muito adequado para lidar com operações de leitura e gravação de arquivos semelhantes.
* Você pode ler ao mesmo tempo ao ler, mas não pode escrever;
*/
Classe estática pública ReadWritelockTest {
// Trancar
ReadWriteLock Lock = new ReentrantreadWritelock ();
// Valor
valor duplo = 0d;
int addtimes = 0;
/**
* Aumente o valor do valor e não permita que vários threads insira o método ao mesmo tempo.
*/
public void AddValue (Double V) {
// Obtenha Writelock e Lock
Bloqueio writeLock = Lock.Writelock ();
writelock.lock ();
System.out.println ("ReadWritelockTest para AddValue:" + V + ""
+ System.currenttimemillis ());
tentar {
Thread.sleep (1000);
} catch (interruptedException e) {
}
tentar {
// Faça o trabalho de escrita
this.value += v;
this.AddTimes ++;
} finalmente {
// Libere o bloqueio de WriteLock
writelock.unlock ();
}
}
/**
* Obtenha informações. Quando um thread está chamando o método AddValue, as informações obtidas pelo getinfo podem estar incorretas.
* Portanto, também é necessário garantir que, quando o método é chamado, nenhum método está chamando o método AddValue.
*/
public String getinfo () {
// Obtenha Readlock e Lock
Lock Readlock = Lock.readlock ();
readlock.lock ();
System.out.println ("ReadWritelockTest to Getinfo"
+ System.currenttimemillis ());
tentar {
Thread.sleep (1000);
} catch (interruptedException e) {
}
tentar {
// Faça o trabalho de leitura
retornar this.value + ":" + this.addtimes;
} finalmente {
// Readlock de liberação
readlock.unlock ();
}
}
}
public static void testReadWriteLockTest () lança exceção {
Final ReadWritelockTest readWritelockTest = new ReadWritelockTest ();
// Crie uma nova tarefa 1 e ligue para o método AddValue de Locktest
Runnable Task_1 = new Runnable () {
public void run () {
readWritelockTest.addvalue (55,55);
}
};
// Crie nova tarefa 2 e chame o método getValue do Locktest
Runnable Task_2 = new Runnable () {
public void run () {
System.out.println ("info:" + readWritelockTest.getInfo ());
}
};
// Crie um novo serviço de execução de tarefas
ExecutorService cachedservice_1 = executores.newcachedthreadpool ();
Futuro futuro_1 = nulo;
// Executa 5 tarefas ao mesmo tempo, das quais as duas primeiras tarefas são Task_1 e as duas últimas tarefas são Task_2
for (int i = 0; i <2; i ++) {
futuro_1 = cachedservice_1.submit (task_1);
}
for (int i = 0; i <2; i ++) {
futuro_1 = cachedservice_1.submit (task_2);
}
// a última tarefa é tarefa_1
futuro_1 = cachedservice_1.submit (task_1);
// A ordem de execução dessas 5 tarefas deve ser:
// O primeiro Task_1 é executado primeiro e o segundo Task_1 é executado novamente;
// Em seguida, dois task_2 são executados ao mesmo tempo;
// porque eles podem ser lidos ao mesmo tempo, eles são executados ao mesmo tempo
// O último Task_1 é executado novamente. Isso ocorre porque você não pode escrever ao ler, então deve esperar até que a leitura termine antes de escrever.
// Aguarde a última tarefa_2 ser executada
futuro_1.get ();
cachedservice_1.shutdownNow ();
}
public static void main (string [] args) lança exceção {
Lockers.testlockTest ();
System.out.println ("-------------------");
Lockers.TestReadWriteLockTest ();
}
}