Open olrlobt opened 11 months ago
Javaλ₯Ό 곡λΆν λ synchronized
ν€μλκ° μ‘΄μ¬νλ κ²μ μκ³ μμμ΅λλ€!
νμ§λ§ λ±ν μ¬μ©νμ§ μμ μμΈν λͺ°λλλ° ν΄λΉ κΈ°νκ° λμ΄μ μ‘°μ¬λ₯Ό ν΄λ³΄μμ΅λλ€.
Synchronized
μλ°μμ λ©ν°μ€λ λλ₯Ό μ΄μ©νλ©΄ μ¬λ¬μμ
μ λμμ μ²λ¦¬ν μ μκΈ° λλ¬Έμ μμ
ν¨μ¨μ΄ μ’μμ§λλ€. νμ§λ§ νλμ 곡μ μμμ μ¬λ¬ μ€λ λμμ λμμ μ κ·Όνμ¬ μ¬μ©νκ² λλ©΄ λλλ‘ μμμΉ λͺ»ν κ²°κ³Όκ° λνλκ² λ©λλ€. μ΄λ¬ν λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ μ¬μ©λλ synchronized
μ λν΄μ μμλ³΄κ² μ΅λλ€.
μλ°μμ μ§μνλ synchroized
ν€μλλ μ¬λ¬κ°μ μ€λ λκ° νκ°μ μμμ μ¬μ©νκ³ μ ν λ, νμ¬ λ°μ΄ν°λ₯Ό μ¬μ©νκ³ μλ ν΄λΉ μ€λ λλ₯Ό μ μΈνκ³ λλ¨Έμ§ μ€λ λ€μ λ°μ΄ν°μ μ κ·Ό ν μ μλλ‘ λ§λ κ°λ
μ
λλ€.
ν΄λΉ ν€μλλ λ³μλ ν¨μμ μ¬μ©ν΄μ λκΈ°νν μ μμ΅λλ€. νμ§λ§ Synchroinzed
λ₯Ό λ¨λ°νλ©΄ μ€νλ € νλ‘κ·Έλ¨ μ±λ₯μ νλ₯Ό μΌμΌν¬ μ μμ΅λλ€. κ·Έ μ΄μ λ μλ° λ΄λΆμ μΌλ‘ λ©μλλ λ³μμ λκΈ°νλ₯Ό νκΈ° μν΄ block
μ unblock
μ μ²λ¦¬νκ² λλλ° μ΄λ° μ²λ¦¬κ° λ§μ΄μ§κ² λλ©΄ μ€νλ € νλ‘κ·Έλ¨ μ±λ₯μ νλ₯Ό μΌμΌν¬ μ μμ΅λλ€.
λ¨Όμ synchronized
κ° νμν μ΄μ λ₯Ό μμ μ½λλ‘ μμ보λλ‘ νκ² μ΅λλ€.
Main
package thread;
import thread.obj.Task;
public class SynchronizedStudy {
public static void main(String[] args) {
Task task = new Task();
Thread threadOne = new Thread(task);
Thread threadTwo = new Thread(task);
threadOne.setName("Thread One");
threadTwo.setName("Thread Two");
threadOne.start();
threadTwo.start();
}
}
Task
λ₯Ό μ΄κΈ°ν ν λ€ Thread
λ₯Ό 2κ° μμ±νμμ΅λλ€. κ° μ€λ λμ μ΄λ¦μ μ€μ ν λ€ μ€ννμμ΅λλ€.
Task
package thread.obj;
import java.util.Random;
public class Task implements Runnable {
private final Random random;
Account account = new Account();
public Task() {
random = new Random();
random.setSeed(System.currentTimeMillis()); // `seed`λ₯Ό λλ€μΌλ‘ μ€μ
}
@Override
public void run() {
while (account.canWithDraw()) {
int money = (random.nextInt(3) + 1) * 100;
account.withDraw(money);
}
}
}
Task
μ€λ λμ
λλ€. Runnable
λ₯Ό implements
νμ¬ run()
μ Override
νμμ΅λλ€.
Money
λ₯Ό 100, 200, 300 μ€ νλμ κ°μ κ°μ Έμ Account
μ withDraw
λ₯Ό μ€νν©λλ€.
Account
package thread.obj;
public class Account {
private int balance = 1000;
public void withDraw(int money) {
if (canWithDrawByMoney(money)) {
try {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + ") μΆκΈ κΈμ‘ : [" + money + "]");
Thread.sleep(1000);
balance -= money;
System.out.println(threadName + ") balance : [" + balance + "]");
} catch (InterruptedException e) {
System.out.println(e.getMessage());
Thread.currentThread().interrupt();
}
}
}
private boolean canWithDrawByMoney(int money) {
return balance >= money;
}
public boolean canWithDraw() {
return balance > 0;
}
}
λ¨μν balance
λ₯Ό money
λ§νΌ μ€μ¬μ£Όλ λ¨κ³ μ
λλ€.
μ€ν κ²°κ³Ό
Thread One) μΆκΈ κΈμ‘ : [100]
Thread Two) μΆκΈ κΈμ‘ : [100]
Thread Two) balance : [900]
Thread Two) μΆκΈ κΈμ‘ : [300]
Thread One) balance : [800]
Thread One) μΆκΈ κΈμ‘ : [100]
Thread One) balance : [700]
Thread One) μΆκΈ κΈμ‘ : [300]
Thread Two) balance : [400]
Thread Two) μΆκΈ κΈμ‘ : [300]
Thread One) balance : [100]
Thread One) μΆκΈ κΈμ‘ : [100]
Thread Two) balance : [-200]
Thread One) balance : [-300]
κ²°κ³Ό νλ©΄μ 보면 μμ‘μ΄ 0μ΄ λ λκΉμ§ μΆκΈμ ν΄μΌνλλ° μμ‘μ΄ λ§μ΄λμ€κ° λμμ΅λλ€.
μ¬κΈ°μ λ©ν°μ€λ λμ λ¬Έμ μ μ΄ λ°κ²¬λμμ΅λλ€. μ΄λ¬ν μ΄μ λ‘ thread-safe
νκΈ° μν΄μ synchronized
ν€μλλ₯Ό μ¬μ©νκ²λ©λλ€.
곡μ λ°μ΄ν°μ λν μ κ·Όκ³Ό μμ μ΄ μ΄λ£¨μ΄μ§λ λ©μλμ synchronized
ν€μλλ₯Ό 리ν΄νμ
μμ λΆμ¬ μ£Όλ©΄ μμ μμ λ ν΄κ²°ν μ μμ΅λλ€.
package thread.obj;
public class Account {
private int balance = 1000;
public synchronized void withDraw(int money) {
if (canWithDrawByMoney(money)) {
try {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + ") μΆκΈ κΈμ‘ : [" + money + "]");
Thread.sleep(1000);
balance -= money;
System.out.println(threadName + ") balance : [" + balance + "]");
} catch (InterruptedException e) {
System.out.println(e.getMessage());
Thread.currentThread().interrupt();
}
}
}
...
}
μ€ν κ²°κ³Ό
Thread One) μΆκΈ κΈμ‘ : [100]
Thread One) balance : [900]
Thread One) μΆκΈ κΈμ‘ : [200]
Thread One) balance : [700]
Thread Two) μΆκΈ κΈμ‘ : [200]
Thread Two) balance : [500]
Thread Two) μΆκΈ κΈμ‘ : [100]
Thread Two) balance : [400]
Thread Two) μΆκΈ κΈμ‘ : [200]
Thread Two) balance : [200]
Thread Two) μΆκΈ κΈμ‘ : [200]
Thread Two) balance : [0]
synchronized
λ₯Ό μ¬μ©νμ¬ thread-safe
λ₯Ό μμΌ°κΈ° λλ¬Έμ λ°μ΄ν°λ λ©μλ μ μ νκ³ μλ μ€λ λκ° μ¨μ ν μμ μ μμ
μΌ λ§μΉ μ μ΄μ΅λλ€.
synchronized
ν€μλλ λ€μκ³Ό κ°μ μ νμμ μ¬μ©ν μ μμ΅λλ€.
μμ μμ μμ μ¬μ©ν λ°©μμ λλ€.
μΈμ€ν΄μ€ λ©μλμ λκΈ°νλ μ΄ λ©μλλ₯Ό κ°μ§ μΈμ€ν΄μ€λ₯Ό κΈ°μ€μΌλ‘ μ΄λ£¨μ΄μ§λλ€. κ·Έλ¬λ―λ‘, ν ν΄λμ€κ° λκΈ°νλ μΈμ€ν΄μ€ λ©μλλ₯Ό κ°μ§λ€λ©΄, μ¬κΈ°μ λκΈ°νλ μ΄ ν΄λμ€μ ν μΈμ€ν΄μ€λ₯Ό κΈ°μ€μΌλ‘ μ΄λ£¨μ΄μ§λλ€. κ·Έλ¦¬κ³ ν μμ μ μ€μ§ νλμ μ°λ λλ§μ΄ λκΈ°νλ μΈμ€ν΄μ€ λ©μλλ₯Ό μ€νν μ μμ΅λλ€.
μ 리νλ©΄ λ μ΄μμ μΈμ€ν΄μ€κ° μλ€λ©΄, ν μμ μ ν μΈμ€ν΄μ€μ ν μ°λ λλ§ μ΄ λ©μλλ₯Ό μ€νμν¬ μ μμ΅λλ€.
μ€νν± λ©μλμ λκΈ°νλ μΈμ€ν΄μ€ λ©μλμ κ°μ λ°©μμΌλ‘ μ΄λ£¨μ΄μ§μ§λ§ JVM
μμ ν΄λμ€ κ°μ²΄λ ν΄λμ€λΉ νλλ§ μ‘΄μ¬ν μ μμΌλ―λ‘, κ°μ ν΄λμ€μ λν΄μ μ€μ§ ν μ°λ λλ§ μ€νν± λ©μλλ₯Ό μ€νν μ μμ΅λλ€.
λ§μΌ λκΈ°νλ μ€νν± λ©μλκ° λ€λ₯Έ ν΄λμ€μ κ°κ° μ‘΄μ¬νλ€λ©΄, μ°λ λλ κ° ν΄λμ€μ λ©μλλ₯Ό μ€νν μ μμ΅λλ€.
package thread.obj;
public class Account {
private static int balance = 1000;
public static synchronized void withDraw(int money) {
if (canWithDrawByMoney(money)) {
try {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + ") μΆκΈ κΈμ‘ : [" + money + "]");
Thread.sleep(1000);
balance -= money;
System.out.println(threadName + ") balance : [" + balance + "]");
} catch (InterruptedException e) {
System.out.println(e.getMessage());
Thread.currentThread().interrupt();
}
}
}
...
}
λ©μλ μμ λκΈ°ν λΈλ‘μ λ°λ‘ μμ±ν μ μμ΅λλ€.
λκΈ°ν λΈλ‘μ΄ κ΄νΈ μμ ν κ°μ²΄λ₯Ό μ λ¬λ°κ³ μμ΅λλ€. μμ μμλ this
κ° μ¬μ©λμλλ° withDraw()
λ©μλκ° νΈμΆλ κ°μ²΄λ₯Ό μλ―Έν©λλ€. μ΄ λκΈ°ν λΈλ‘ μμ μ λ¬λ κ°μ²΄λ₯Ό λͺ¨λν° κ°μ²΄λΌ ν©λλ€. μ΄ μ½λλ λͺ¨λν° κ°μ²΄λ₯Ό κΈ°μ€μΌλ‘ λκΈ°νκ° μ΄λ£¨μ΄μ§κ³ μμ΅λλ€.
κ°μ λͺ¨λν° κ°μ²΄λ₯Ό κΈ°μ€μΌλ‘ λκΈ°νλ λΈλ‘ μμ μ½λλ₯Ό μ€μ§ ν μ°λ λλ§μ΄ μ€νν μ μμ΅λλ€.
package thread.obj;
public class Account {
private int balance = 1000;
public void withDraw(int money) {
synchronized (this) {
if (canWithDrawByMoney(money)) {
try {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + ") μΆκΈ κΈμ‘ : [" + money + "]");
this.wait(1000);
balance -= money;
System.out.println(threadName + ") balance : [" + balance + "]");
} catch (InterruptedException e) {
System.out.println(e.getMessage());
Thread.currentThread().interrupt();
}
}
}
}
...
}
π« Info
SonarLint
μ μ μ½λ λΆμ λꡬμμλ μΈμ€ν΄μ€ λ©μλ λ°©λ²λ³΄λ€λ μΈμ€ν΄μ€ λ©μλ μμ λκΈ°ν λΈλμ κΆμ₯νκ³ μμ΅λλ€.
package thread.obj;
public class Account {
private static int balance = 1000;
public static void withDraw(int money) {
synchronized (Account.class) {
if (canWithDrawByMoney(money)) {
try {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + ") μΆκΈ κΈμ‘ : [" + money + "]");
Thread.sleep(1000);
balance -= money;
System.out.println(threadName + ") balance : [" + balance + "]");
} catch (InterruptedException e) {
System.out.println(e.getMessage());
Thread.currentThread().interrupt();
}
}
}
}
private static boolean canWithDrawByMoney(int money) {
return balance >= money;
}
public boolean canWithDraw() {
return balance > 0;
}
}
μμμ μ°¨μ΄λ static
μ μ¬μ©νμκΈ° λλ¬Έμ class
λ₯Ό λ£μ΄μΌ ν©λλ€.
κ·ΈλΌ λ³Έλ‘ μΌλ‘ λμμμ synchronized
κ° μ±λ₯μ νλ₯Ό μΌμΌν€λ μ΄μ μ λν΄μ μμλ³΄κ² μ΅λλ€.
synchronized
λΈλ‘μ κ²½ν©νμ¬ μ κ·Όνλ €κ³ ν λ, κ²½ν©μ΄ λ°μν μ μμ΅λλ€. μ΄λ‘ μΈν΄ μ€λ λκ° λκΈ°νκ³ κ²½ν©μ ν΄κ²°νκΈ° μν΄ μμ€ν
리μμ€κ° λλΉλ©λλ€.synchronized
λΈλ‘μμ μ€λ λ κ°μ κ²½ν©μ΄ λ°μνλ©΄ μ€λ λκ° λκΈ° μνλ‘ μ νλκ³ λ€λ₯Έ μ€λ λλ‘ μ νλ©λλ€. μ΄λ¬ν λ¬Έλ§₯ μ ν λΉμ©μ μ±λ₯μ μ νμν΅λλ€.synchronized
λΈλ‘μ μ€μ²©νμ¬ μ¬μ©νκ±°λ ν΄λμ€ μμ€μμ synchronized
λΈλ‘μ μ¬μ©νλ©΄ λλΈ λ½ λ¬Έμ κ° λ°μν μ μμΌλ©°, μ΄λ μ±λ₯ μ νμ μμΈμ΄ λ μ μμ΅λλ€.public void withDraw(int money) {
synchronized (this) {
if (canWithDrawByMoney(money)) {
try {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + ") μΆκΈ κΈμ‘ : [" + money + "]");
Thread.sleep(1000);
balance -= money;
System.out.println(threadName + ") balance : [" + balance + "]");
doubleLock();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
Thread.currentThread().interrupt();
}
}
}
}
private void doubleLock() {
synchronized (this) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
Thread.currentThread().interrupt();
}
}
}
μ€μ λ‘ μ€λ¬΄μμλ synchronized
λ₯Ό λ§μ΄ μ¬μ©νμ§ μλλ° μ΄ λ°©λ²μ μ±λ₯μ μΉλͺ
μ μ΄κΈ° λλ¬Έμ
λλ€. λ°λΌμ synchronized
μ¬μ©μ μ§μν΄μΌν©λλ€. λμμ±μ 보μ₯ν΄μΌ νλ κ²½μ°μλ μλ°κ° μ 곡νλ thread-safe
ν μλ£κ΅¬μ‘°λ₯Ό μ¬μ©ν΄μΌν©λλ€.
(ConcurrentHashMap
, BlockingQueue
λ±)
JSP
μ include
λ λμ μΌλ‘λν μ μκ³ μ μ μΌλ‘λ ν μ μμ΅λλ€.
κ·Έλ¬λ©΄ κ° λ°©μμ λν μ₯μ κ³Ό λ¨μ μ μμ보λλ‘ νκ³ μ΄λ ν λ°©μμ μ¬μ©ν΄μΌνλ μ§ κ³ λ € μ¬νμ μμ±ν΄λ³΄κ² μ΅λλ€.
JSP
νμ΄μ§λ₯Ό μλ²μμ μ»΄νμΌ ν λ, include
λ λ΄μ©μ ν΄λΉ μμΉμ μ μ μΌλ‘ μ½μ
ν©λλ€.
μ΄ λ°©μμ jsp:include
λλ <%@ include %>
λλ ν°λΈλ₯Ό μ¬μ©νμ¬ κ΅¬νν©λλ€.
μ΄ λ°©μμ λν μ₯λ¨μ μ λ€μκ³Ό κ°μ΅λλ€.2)
include
νμ΄μ§μ μ μΈν λ³μλ₯Ό λΆλͺ¨νμ΄μ§μμ λ³λμ λ³μ μ μΈμμ΄ μ¬μ©μ΄ κ°λ₯νμ§λ§ λΆλͺ¨ νμ΄μ§μ include
ν νμΌμ΄ λ§μκ²½μ° include
νμ΄μ§μμ μ μΈλ λ³μλ₯Ό μΆμ ν΄μΌν μ μ§λ³΄μν λ νλλλ€.JSP
νμΌμ html
μ΄ λ§μμ§κ³ Java
λ‘μ§λ λ§μμ§λ©΄ λΌμΈ μκ° λμ΄λκ² λλλ° μ΄ λ λͺ¨λ λΆλΆμ μ μ μΌλ‘ ν λΉνλ©΄ μλμ κ°μ μλ¬λ‘κ·Έλ₯Ό λ§λ μ μμ΅λλ€.1)
Generated servlet error: The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes limit
μ μ include
λ°©λ²μ νμ©νμ¬ 10,000λΌμΈ μ λ λμ΄κ°λ©΄ ν΄λΉ μλ¬λ₯Ό λ§λκ² λ μ μμ΅λλ€.JSP
νμ΄μ§κ° μ€νλ λ, include
λ λ΄μ©μ λμ μΌλ‘ μ€ννκ³ νμ΄μ§μ μ€ν νλ¦ μ€μ λ€λ₯Έ JSP
νμ΄μ§λ₯Ό ν¬ν¨μν΅λλ€.
μ΄ λ°©μμ <jsp:include>
λλ Java μ½λλ₯Ό μ¬μ©νμ¬ κ΅¬νν©λλ€.
μ΄ λ°©μμ λν μ₯λ¨μ μ λ€μκ³Ό κ°μ΅λλ€.2)
include
νμ΄μ§λ λ³μλ₯Ό 곡μ νμ§ μμΌλ―λ‘ μ μ§ λ³΄μμ νΈν©λλ€. νμ§λ§ λΆλͺ¨νμ΄μ§μμ include
ν νμΌμμ λ³μλ₯Ό μ¬μ©μ <jsp:param name="userName" value="<%=userName%>"/>
μ κ°μ΄ λΆλͺ¨νμ΄μ§μμ μ§μ ν΄ μ£Όμ΄μΌ ν©λλ€.include
λ μλ² λΆνλ₯Ό μ¦κ°μν¬ μ μμΌλ―λ‘, κΌ νμν λΆλΆμλ§ λμ include
λ₯Ό μ¬μ©ν΄μΌ ν©λλ€.
μ μ include
λ μΌλ°μ μΌλ‘ μλ² λΆνμ μν₯μ λ―ΈμΉμ§ μμ΅λλ€.include
κ° λ§μ΄ μ¬μ©λ κ²½μ°, μλ΅ μκ°μ΄ λλ €μ§ μ μμ΅λλ€.
μ΄λ₯Ό μ΅μννλ €λ©΄ μ μ ν μΊμ± μ λ΅μ κ³ λ €ν΄μΌ ν©λλ€.include
λ₯Ό μ¬μ©νλ©΄ λ³μλ₯Ό 곡μ ν μ μμΌλ―λ‘, μκΈ°μΉ λͺ»ν λ¬Έμ κ° λ°μν μ μμ΅λλ€.
λ³μλ₯Ό 곡μ ν μ μμΌλ―λ‘, μκΈ°μΉ λͺ»ν λ¬Έμ κ° λ°μν μ μμ΅λλ€. λ³μμ μ€μ½νμ μΆ©λμ λ°©μ§νκΈ° μν΄ λ³μλͺ
μ μ μ€νκ² μ ννκ³ , λ³μ μ€μ½νλ₯Ό μ μ΄νλ λ°©λ²μ μ΄ν΄ν΄μΌ ν©λλ€.include
λ₯Ό μ¬μ©νλ©΄ λμ λ°μ΄ν°λ₯Ό νμ΄μ§μ ν¬ν¨μν¬ μ μμΌλ―λ‘, μ μ°μ±μ΄ ν₯μλ©λλ€.
μ΄λ₯Ό ν΅ν΄ λμ μΌλ‘ νμ΄μ§λ₯Ό ꡬμ±νκ³ λ€μν μ½ν
μΈ λ₯Ό μμ±ν μ μμ΅λλ€.
π λ¬Έμ
24μ₯ μ 리λ λ΄μ©μ 보λ€λ³΄λ, μ¬κ±Έ! λ°°μ΄ κ² κ°μ λ΄μ©μΈλ° λ¨Έλ¦Ώμμ ?κ° κ°λ μκ²Όλ€.
μ λ΄μ©λ€μ μμ μ ν¨κ» μ΄μ λ₯Ό μ€λͺ ν΄μ£Όλ©΄ μ’μ κ² κ°λ€!
βοΈ μ μ λ°°κ²½
λ΄ λ¨Έλ¦Ώμμ μ§μ°κ°
πΊ κ΄λ ¨ μ±ν° λ° λ νΌλ°μ€
κ΄λ ¨ μ±ν°μ μΆμ²λ₯Ό μ μ΄μ£ΌμΈμ
story. 24 425p.
π³ λΉκ³