Java가 synchronized 수식 방법을 사용하여 스레드를 동기화하는 실례 설명
7205 단어 Javasynchronized라인
예제 1
먼저 첫 번째 예시를 보면 자바에서 같은 대상의 임계 구역은 같은 시간에 접근할 수 있는 것이 하나밖에 없다(비정적 synchronized 방법).
package concurrency;
public class Main8 {
public static void main(String[] args) {
Account account = new Account();
account.setBalance(1000);
Company company = new Company(account);
Thread companyThread = new Thread(company);
Bank bank = new Bank(account);
Thread bankThread = new Thread(bank);
System.out.printf("Account : Initial Balance: %f
", account.getBalance());
companyThread.start();
bankThread.start();
try {
//join()
companyThread.join();
bankThread.join();
System.out.printf("Account : Final Balance: %f
", account.getBalance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/* */
class Account{
private double balance;
/* balance */
public synchronized void addAmount(double amount){
double tmp = balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp += amount;
balance = tmp;
}
/* balance */
public synchronized void subtractAmount(double amount){
double tmp = balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp -= amount;
balance = tmp;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
/* */
class Bank implements Runnable{
private Account account;
public Bank(Account account){
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.subtractAmount(1000);
}
}
}
/* */
class Company implements Runnable{
private Account account;
public Company(Account account){
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.addAmount(1000);
}
}
}
너는 잔액을 충전하고 공제할 수 있는 은행 계좌의 시뮬레이션 응용 프로그램을 개발했다.이 프로그램은addAmount() 방법을 100회 호출하여 계좌를 충전하여 매번 1000씩 입금합니다.그리고 100번subtract Amount() 방법으로 계좌 잔액을 공제하고 매번 1000씩 공제한다.우리는 계좌의 최종 잔액이 초기 잔액과 같기를 기대한다. 우리는synchronized 키워드를 통해 실현되었다.공유 데이터의 병렬 접근 문제를 보려면addAmount () 와subtractAmount () 방법 설명에 있는synchronized 키워드를 삭제하면 됩니다.synchronized 키워드가 없는 상황에서 출력된 잔액 값은 일치하지 않습니다.이 프로그램을 여러 번 실행하면 다른 결과를 얻을 수 있습니다.JVM은 스레드의 실행 순서를 보장하지 않기 때문에 매번 실행할 때마다 스레드는 서로 다른 순서로 계정의 잔액을 읽고 수정하여 최종 결과도 다르다.
하나의 대상의 방법은synchronized 키워드로 설명되며, 하나의 라인에만 접근할 수 있습니다.스레드 A가 동기화 방법인 syncmethodA () 를 실행하고 있다면, 스레드 B가 이 대상의 다른 동기화 방법인 syncmethodB () 를 실행하려면, 스레드 B는 스레드 A가 접근할 때까지 막힙니다.그러나 만약 스레드 B가 같은 종류의 다른 대상에 접근한다면 두 스레드는 모두 막히지 않을 것이다.
예제 2
같은 대상의 정적synchronized 방법과 비정적synchronized 방법이 같은 시간에 여러 라인에 접근할 수 있는 문제를 보여 주고 검증해 보세요.
package concurrency;
public class Main8 {
public static void main(String[] args) {
Account account = new Account();
account.setBalance(1000);
Company company = new Company(account);
Thread companyThread = new Thread(company);
Bank bank = new Bank(account);
Thread bankThread = new Thread(bank);
System.out.printf("Account : Initial Balance: %f
", account.getBalance());
companyThread.start();
bankThread.start();
try {
//join()
companyThread.join();
bankThread.join();
System.out.printf("Account : Final Balance: %f
", account.getBalance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/* */
class Account{
/* */
private static double balance = 0;
/* balance , static */
public static synchronized void addAmount(double amount){
double tmp = balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp += amount;
balance = tmp;
}
/* balance */
public synchronized void subtractAmount(double amount){
double tmp = balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp -= amount;
balance = tmp;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
/* */
class Bank implements Runnable{
private Account account;
public Bank(Account account){
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.subtractAmount(1000);
}
}
}
/* */
class Company implements Runnable{
private Account account;
public Company(Account account){
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.addAmount(1000);
}
}
}
나는 단지 지난 예에서 balance에 static 키워드 수정을 추가했고addAmount () 방법도 static 키워드를 수식할 수 있다.실행 결과는 여러분 스스로 테스트해 보세요. 매번 실행할 때마다 다른 결과입니다!요약:
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.