<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>woo_b.log</title>
        <link>https://velog.io/</link>
        <description>백엔드개발자</description>
        <lastBuildDate>Tue, 12 Mar 2024 12:17:25 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>woo_b.log</title>
            <url>https://velog.velcdn.com/images/woo_be/profile/28bc0967-9626-4de0-a0eb-ae1e7860a04e/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. woo_b.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/woo_be" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Synchronization Control - #5]]></title>
            <link>https://velog.io/@woo_be/Synchronization-Control-6</link>
            <guid>https://velog.io/@woo_be/Synchronization-Control-6</guid>
            <pubDate>Tue, 12 Mar 2024 12:17:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>실습 자료 : <a href="https://github.com/helloJosh/nhn-homework-thread-study">https://github.com/helloJosh/nhn-homework-thread-study</a></p>
</blockquote>
<h1 id="1-synchronization-control">1. Synchronization Control</h1>
<p>자바에서는 synchronized method, block을 제어하기 위해 wait(), notify(), notifyAll()을 지원한다. 네트워크 프로그래밍이 이런 식으로 프로그래밍되어있어 은근 중요한 부분 같다.</p>
<ul>
<li>Wait() : syncrhonized 영역에서 lock을 소유한 thread가 어떠한 이유에서 자신의 제어권을 양보하고 WAITING 또는 TIMED_WAITING 상태에서 대기하기 위해서 사용된다.</li>
<li>notify()와 notifyAll() : syncrhonized 영역에서 WAITING 상태에 있는 다른 thread를 다시 RUNNABLE 상태로 변경시키는 역할을 한다.<blockquote>
<p>wait, notify, notifyAll은 Thread의 static method가 아닌 instance method이다.</p>
</blockquote>
</li>
</ul>
<h4 id="코드로-알아보자">코드로 알아보자</h4>
<pre><code class="language-java">public class Data {
    private String packet;
    private boolean transfer = true;

    public synchronized String receive(){
        while(transfer){
            try{
                wait();
                //Thread.sleep(1000); 계속 리시버만 돌고 있다.
            } catch (InterruptedException e){
                Thread.currentThread().interrupt();
            }
        }
        transfer = true;

        String returnPacket = packet;
        notifyAll();
        return returnPacket;
    }
    public synchronized void send(String packet){
        while(!transfer){
            try{
                wait();
            } catch (InterruptedException e){
                Thread.currentThread().interrupt();
            }
        }
        transfer = false;
        this.packet = packet;
        notifyAll();
    }
    public static void main(String[] args) {
        Data data = new Data();

        Thread sender = new Thread(new Sender(data));
        Thread receiver1 = new Thread(new Receiver(data));
        Thread receiver2 = new Thread(new Receiver(data));

        sender.start();
        receiver1.start();
        receiver2.start();
    }
}</code></pre>
<pre><code class="language-java">public class Receiver implements Runnable{
    private Data load;
    public Receiver(Data load) {
        this.load = load;
    }
    public void run(){
        for(String receivedMessage = load.receive(); !&quot;End&quot;.equals(receivedMessage);receivedMessage= load.receive()){
            System.out.println(receivedMessage);
            try{
                Thread.sleep(ThreadLocalRandom.current().nextInt(1000,5000));
            } catch (InterruptedException e){
                Thread.currentThread().interrupt();
                System.err.println(&quot;Thread Interrupted&quot;);
            }
        }
    }
}</code></pre>
<pre><code class="language-java">public class Sender implements Runnable {
    private Data data;
    public Sender(Data data) {
        this.data = data;
    }
    public void run(){
        String packets[] ={
            &quot;1st packet&quot;,
            &quot;2nd packet&quot;,
            &quot;3rd packet&quot;,
            &quot;4th packet&quot;,
            &quot;End&quot;
        };

        for(String packet : packets){
            data.send(packet);
            try{
                Thread.sleep(ThreadLocalRandom.current().nextInt(1000,5000));
            } catch (InterruptedException e){
                Thread.currentThread().interrupt();
                System.err.println(&quot;Thread Interrupted&quot;);
            }
        }
    }
}</code></pre>
<ul>
<li>위 와 같이 Data Class에서 method에서 wait()을 호출해서 다른 thread가 일이 끝날 때까지 기다린다.</li>
<li>일이 끝난 쓰레드는 notifyAll()을 호출하여 일이 끝났다는 것을 다른 쓰레드에게 알려준다.</li>
</ul>
<blockquote>
<p>참고</p>
</blockquote>
<ul>
<li>위에 주석에 있는 것처럼 wait() 과 sleep()은 다르다.</li>
<li>wait()은 공유 자원에 접근 안한 상태로 대기중인 것이고</li>
<li>sleep()은 자원을 갖고 있는 상태에서 쉬는 것이다.</li>
<li>따라서 wait()을 주석하고 sleep()를 주석을 풀게되면 Receiver만 돌게 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Thread Synchronization(쓰레드 동기화) - #4]]></title>
            <link>https://velog.io/@woo_be/Thread-Synchronization%EC%93%B0%EB%A0%88%EB%93%9C-%EB%8F%99%EA%B8%B0%ED%99%94-4</link>
            <guid>https://velog.io/@woo_be/Thread-Synchronization%EC%93%B0%EB%A0%88%EB%93%9C-%EB%8F%99%EA%B8%B0%ED%99%94-4</guid>
            <pubDate>Tue, 12 Mar 2024 11:39:34 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이번에도 공부하며 실습한 코드는 <a href="https://github.com/helloJosh/nhn-homework-thread-study">https://github.com/helloJosh/nhn-homework-thread-study</a> 에 올리겠습니다
-0317 Synchronized 내용추가</p>
</blockquote>
<h1 id="1-thread-동기화">1. Thread 동기화</h1>
<h3 id="멀티-쓰레드를-사용할-경우-공동으로-사용하는-메모리를-update할-경우-문제가-발생한다">멀티 쓰레드를 사용할 경우 공동으로 사용하는 메모리를 update할 경우 문제가 발생한다.</h3>
<p>바로 코드로 알아보자</p>
<pre><code class="language-java">public class SharedCounterV0 extends Thread{    
    SharedCountV0 sharedCount;
    int count;
    int maxCount;

    public SharedCounterV0(String name, int maxCount, SharedCountV0 sharedCount) {
        setName(name);
        this.sharedCount = sharedCount;
        this.maxCount = maxCount;
        count = 0;
    }

    @Override
    public void run() {
        while (count &lt; maxCount) {
            count++;
            sharedCount.increment();
        }
    }
}</code></pre>
<pre><code class="language-java">public class SharedCountV0 {    
    int count;
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
    public void increment() {
        setCount(getCount() + 1);
    }
}
</code></pre>
<pre><code class="language-java">public static void main(String[] args) throws InterruptedException {        
        SharedCountV0 sharedCount = new SharedCountV0();
        SharedCounterV0 counter1 = new SharedCounterV0(&quot;counter1&quot;, 10000, sharedCount);
        SharedCounterV0 counter2 = new SharedCounterV0(&quot;counter2&quot;, 10000, sharedCount);

        counter1.start();
        counter2.start();
        System.out.println(counter1.getName() + &quot;: started&quot;);
        System.out.println(counter2.getName() + &quot;: started&quot;);

        counter1.join();
        counter2.join();
        System.out.println(counter1.getName() + &quot;: terminated&quot;);
        System.out.println(counter2.getName() + &quot;: terminated&quot;);

        System.out.println(&quot;sharedCount : &quot; + sharedCount.getCount());
    }</code></pre>
<p><img src="https://velog.velcdn.com/images/woo_be/post/fe446766-d540-4251-a1d3-6da4b49135f3/image.png" alt=""></p>
<p>이렇게 결과 화면으로 20000 결과가 아닌 12833으로 다른 결과가 나온 것을 알 수 있다.</p>
<h3 id="해결방법">해결방법</h3>
<ul>
<li>메소드 앞에 Synchronized Method를 붙이거나<pre><code class="language-java">public synchronized void increment() {
      setCount(getCount() + 1);
}</code></pre>
</li>
<li>메소드 호출 부에 Synchronized Block을 통해 감싼다.<pre><code class="language-java">@Override
public void run() {
  while (count &lt; maxCount) {
      count++;
      synchronized(sharedCount){
          sharedCount.increment();
      }
  }
}</code></pre>
<blockquote>
<h4 id="참고">참고</h4>
<p>위 코드를 봐서 알겠지만 블럭에서 sychronized 메서드가 자신의 인스턴스를 매개변수로 갖는 것을 알 수 있다. 따라서 임계 구역 또는 공유 자원에 들어갈 때 인스턴스, 오브젝트 단위로 Lock()을 하고 빠져 나올때 Unlock()을 통해 상호배제를 이루어낸다.
또한 자바에서는 Monitor 방식으로 sychronized가 구현되고있다.</p>
</blockquote>
</li>
</ul>
<h1 id="2-용어정리">2. 용어정리</h1>
<ul>
<li>Critical Section(임계구역) : 공유 자원</li>
<li>Mutual Exclusion(상호배제) : Race Condition을 해결하기 위해 공유 자원 접근을 하나의 process, thread로 제한 하는 것(Synchronized) </li>
<li>Race Condition(경쟁조건) : 둘 이상의 Thread가 동시에 공유 자원 접근시 발생하는 현상</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Thread Object 관리 - #3]]></title>
            <link>https://velog.io/@woo_be/Thread-Object-%EA%B4%80%EB%A6%AC-3</link>
            <guid>https://velog.io/@woo_be/Thread-Object-%EA%B4%80%EB%A6%AC-3</guid>
            <pubDate>Mon, 11 Mar 2024 13:19:21 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>전편의 Runnable Interface를 이용한 Thread를 구현의 뒷편입니다.
제가 실습한 코드는 혹시 몰라 올려둡니다. <a href="https://github.com/helloJosh/nhn-homework-thread-study">https://github.com/helloJosh/nhn-homework-thread-study</a></p>
</blockquote>
<h1 id="1-thread-object-관리">1. Thread object 관리</h1>
<h3 id="runnable-interface를-이용할-경우-별도의-thread-object-관리가-필요합니다">Runnable interface를 이용할 경우 별도의 Thread object 관리가 필요합니다.</h3>
<ol>
<li>생성 후 자동 종료될때 자동 삭제한다.</li>
<li>구현되는 Class 내에 Thread obejct를 포함시켜 관리한다.</li>
<li>Thread Pool을 이용한다.</li>
</ol>
<h1 id="2-생성-후-종료-자동-삭제">2. 생성 후 종료 자동 삭제</h1>
<pre><code class="language-java">public class RunnableThreadCounter implements Runnable{
    String name;
    int count;
    int maxCount;

    public RunnableThreadCounter(String name, int maxCount){
        // 중략
    }
    // Gett 중략
    @Override
    public void run(){
        while(count &lt; maxCount){
            try{
                Thread.sleep(1000);
                count++;
                System.out.println(name +&quot;:&quot;+count);
            } catch (InterruptedException e) {
                System.out.println(name+&quot;: interrupted&quot;);
                Thread.currentThread().interrupt();
            }
        }
    }
    public static void main(String[] args) {
        RunnableCounter counter = new RunnableCounter(&quot;counter&quot;, 5);
        Thread thread = new Thread(counter);

        thread.start();
    }
}
</code></pre>
<ul>
<li>간편하지만 몇가지 문제점이 있다.</li>
<li>Counter와 Thread의 연결관계의 모호함</li>
<li>특정 Instance가 동작중을 확인하거나 멈추기엔 힘든코드이다.</li>
</ul>
<h1 id="3class내에서-thread를-field로-포함">3.Class내에서 Thread를 field로 포함</h1>
<pre><code class="language-java">public class RunnableThreadCounter implements Runnable{
    String name;
    int count;
    int maxCount;
    Thread thread;

    public RunnableThreadCounter(String name, int maxCount){
        this.name = name;
        this.maxCount = maxCount;
        count =0;
        thread = new Thread(this);
    }
    public void start(){
        thread.start();
    }
    public void stop(){
        //thread.currentThread().interrupt();
        thread.interrupt();
    }
    public Thread getThread(){
        return this.thread;
    }
    // Getter 중략
    @Override
    public void run(){
        while(!Thread.currentThread().isInterrupted() &amp;&amp; count &lt; maxCount){
            try{
                Thread.sleep(1000);
                count++;
                System.out.println(name +&quot;:&quot;+count);
            } catch (InterruptedException e) {
                System.out.println(name+&quot;: interrupted&quot;);
                Thread.currentThread().interrupt();
            }
        }
    }
    public static void main(String[] args) {
        RunnableThreadCounter[] counters = new RunnableThreadCounter[10];
        Thread[] threads = new Thread[10];
        LocalTime now = LocalTime.now();
        boolean allStopped = false;

        for(int i=0; i&lt;counters.length ; i++){
                counters[i] = new RunnableThreadCounter(&quot;counter &quot;+(i+1), 10);
                counters[i].getThread().start();
        }

        while(!allStopped){
            if((counters[0].getCount()&gt;5)){
                for(int i=0;i&lt;counters.length;i++){
                    counters[i].getThread().interrupt();
                }
            }
            allStopped = true;
            for(int i=0;i&lt;counters.length;i++){
                if(counters[i].getThread().isAlive()){
                    allStopped = false;
                }
            }
        }
        System.out.println(&quot;end :&quot; + now);
    }
}</code></pre>
<ul>
<li>이런식으로 Thread를 field로 추가함으로써 어떤 Counter, Thread에 연결짓거나 특정 지을 수 있다.</li>
</ul>
<blockquote>
<h3 id="참고1">참고1</h3>
<p><code>Thread.interrupt()</code> , <code>Thread.currentThread().interrupt()</code>는 완전히 다른 코드이다. 
<code>Thread</code>는 필드에 저장된 Thread를 의미하고 <code>Thread.currentThread</code>는 현재 돌고 있는 Thread를 의미한다. 즉 <code>CurrentThread()</code> 함수를 사용하면 Main Thread까지 튀어나오니 조심해야한다.</p>
</blockquote>
<blockquote>
<h3 id="참고2">참고2</h3>
<p>Thread 프로그래밍할때는 디버깅 모드가 제대로 작동하지 않아 Log나 콘솔에 직접 찍어줘야한다. 디버깅 모드로 실행시 원래 결과값과 다른 값이 나온다.
코드와는 다르게 생각해야하는 것 같다.</p>
</blockquote>
<h1 id="4-thread-pool">4. Thread Pool</h1>
<p>ExecutorService를 이용해 thread pool을 생성한다. 이때, pool의 크기는 1로 한다.</p>
<pre><code class="language-java">ExecutorService pool = Executors.newFixedThreadPool(1);</code></pre>
<p>Thread pool에 RunnableCounter instance를 생성해 넘기고 실행하도록 한다.</p>
<pre><code class="language-java">pool.execute(new RunnableCounter(&quot;counter1&quot;, 5));
pool.execute(new RunnableCounter(&quot;counter2&quot;, 5));</code></pre>
<p>Thread pool을 종료하도록 명령을 내리고, 종료되길 기다린다.</p>
<pre><code class="language-java">pool.shutdown();
System.out.println(&quot;Shutdown called&quot;);
while (!pool.awaitTermination(2, TimeUnit.SECONDS)) {
    System.out.println(&quot;Not yet finished&quot;);
}
System.out.println(&quot;All service finished&quot;);</code></pre>
<h1 id="5-class-확장-vs-interface-구현-thread">5. Class 확장 vs Interface 구현 Thread</h1>
<table>
<thead>
<tr>
<th align="left">Class 확장</th>
<th align="left">Interface 구현</th>
</tr>
</thead>
<tbody><tr>
<td align="left">multiple inheritance을 지원하지 않으므로, 다른 class로부터의 추가적인 확장이 불가능하다.</td>
<td align="left">Interface에 대한 multiple inheritance가 지원되고, 구현된 후에도 해당 class의 확장이 가능하다</td>
</tr>
<tr>
<td align="left">Instance 생성 후 바로 실행할 수 있다.</td>
<td align="left">Instance 생성 후 바로 사용할 수 없고, 추가적인 Thread object가 요구된다.</td>
</tr>
<tr>
<td align="left">간단한 class라도 별도의 class 정의가 필요하다.</td>
<td align="left">Runnable interface는 functional interface로 Lambda로 구현 가능하다.</td>
</tr>
</tbody></table>
<ul>
<li>각각의 장,단점이 있기 때문에 필요할때 사용하면 될 것 같다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Thread Counter 구현 - #2]]></title>
            <link>https://velog.io/@woo_be/Thread-Counter-%EA%B5%AC%ED%98%84-2</link>
            <guid>https://velog.io/@woo_be/Thread-Counter-%EA%B5%AC%ED%98%84-2</guid>
            <pubDate>Mon, 11 Mar 2024 12:47:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>전편에는 Thread에 대한 개요를 공부했었고 이번 편에서는 Java를 통해서 Thread를 공부해나가 볼까 합니다. 공부 중이기 때문에 틀린 부분있으면 지적 꼭 좀 부탁드립니다. 이 글 또한 도움이 됐으면 좋겠습니다😀
제가 실습한 코드는 혹시 몰라 올려둡니다. <a href="https://github.com/helloJosh/nhn-homework-thread-study">https://github.com/helloJosh/nhn-homework-thread-study</a></p>
</blockquote>
<h1 id="1-thread-counter---2가지-main-함수">1. Thread Counter - 2가지 Main 함수</h1>
<pre><code class="language-java">public class RunnableCounter implements Runnable{
    String name;
    int count;
    int maxCount;
    public RunnableCounter(String name, int maxCount){
        // 생성자 중략
    }
    @Override
    public void run(){
        while(count &lt; maxCount){
            try{
                Thread.sleep(1000);
                count++;
                System.out.println(name +&quot;:&quot;+count);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }</code></pre>
<p>Counter Class 구현 코드</p>
<pre><code class="language-java">public static void main(String[] args) {
        LocalTime now = LocalTime.now();
        RunnableCounter counter1 = new RunnableCounter(&quot;counter1&quot;, 10);
        RunnableCounter counter2 = new RunnableCounter(&quot;counter2&quot;, 10);

        System.out.println(&quot;start :&quot; + now);

        counter1.run();
        counter2.run();

        System.out.println(&quot;end :&quot; + now);
    }</code></pre>
<pre><code class="language-java">public static void main(String[] args) {
        LocalTime now = LocalTime.now();
        RunnableCounter counter1 = new RunnableCounter(&quot;counter1&quot;, 10);
        RunnableCounter counter2 = new RunnableCounter(&quot;counter2&quot;, 10);
        Thread thread1 = new Thread(counter1);
        Thread thread2 = new Thread(counter2);

        System.out.println(&quot;start :&quot; + now);

        thread1.start();
        thread2.start();

        System.out.println(&quot;end :&quot; + now);
    }</code></pre>
<h4 id="무슨-차이일까">무슨 차이일까</h4>
<ul>
<li>첫번째 메인코드는 Main 쓰레드가 계속 돌면서 Start+시간을 찍고 Counter를 찍고 마지막에 End+시간을 찍는다.</li>
<li>두번째 코드는 Main이 아닌 쓰레드가 돌아 Start, End를 찍고 Counter가 찍힌다.</li>
<li>즉, Start() 함수는 Linux의 Fork와 같이 쓰레드를 복사하고 할당해준다.<p align="center">
<img src="https://velog.velcdn.com/images/woo_be/post/550d411c-4b94-43b7-a86a-1cc4ce22454c/image.png" width="50%" height="50%" align="center">
</p></li>
<li>run()의 경우 CallStack에서 Thread Main만 돌고 있는 것을 알 수 있다.<p align="center">
<img src="https://velog.velcdn.com/images/woo_be/post/03480a7c-5ffe-47fd-a130-0d655f61f9cd/image.png" width="50%" height="50%">
</p></li>
<li>start()의 경우 CallStack에서 Main이 아닌 다른 Thread-0 이라는 것을 볼 수 있다.</li>
</ul>
<h1 id="2-thread-할당">2. Thread 할당</h1>
<pre><code class="language-java">public static void main(String[] args) {
        LocalTime now = LocalTime.now();
        RunnableCounter counter1 = new RunnableCounter(&quot;counter1&quot;, 10);
        RunnableCounter counter2 = new RunnableCounter(&quot;counter2&quot;, 10);
        Thread thread1 = new Thread(counter1);
        Thread thread2 = new Thread(counter2);

        System.out.println(&quot;start :&quot; + now);

        thread1.start();
        thread2.start();

        while(thread1.isAlive() || thread2.isAlive())
            ;
        System.out.println(&quot;end :&quot; + now);
    }</code></pre>
<ul>
<li>위와 같이 Thread를 직접 할당할 수 있고 run()을 사용했던 Main코드와 똑같이 출력을 만들어 낼 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Process(프로세스) vs Thread(쓰레드) - #1]]></title>
            <link>https://velog.io/@woo_be/Thread-Test</link>
            <guid>https://velog.io/@woo_be/Thread-Test</guid>
            <pubDate>Mon, 11 Mar 2024 08:19:46 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>쓰레드를 공부하면서 중요하다고 생각하는 것을 곱십고 정리해서 여러편으로 나눠서 올릴 생각입니다. 기본적으로 제가 보기 위해서 작성하는 것이지만 다른 분들도 도움이 됐으면 좋겠습니다. 😀
제가 실습한 코드는 혹시 몰라 올려둡니다. <a href="https://github.com/helloJosh/nhn-homework-thread-study">https://github.com/helloJosh/nhn-homework-thread-study</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/woo_be/post/5bbe2cf6-aeeb-43d9-8867-bf62e53350c0/image.png" alt=""></p>
<h1 id="1-process">1. Process</h1>
<ul>
<li>실행 중인 프로그램을 의미</li>
<li>더 자세히 말하면, 코드를 컴파일하여 프로그램을 실행시키면, 메모리 할당이 이루어지고 컴파일된 바이너리 코드가 올라가게되어 프로그램이 실행되고 이 순간부터 process라고 부른다.</li>
</ul>
<h1 id="2-thread">2. Thread</h1>
<ul>
<li>Process와 유사하지만, 메모리를 공유하여 한 Process에 많은 Thread가 존재할 수 있다.</li>
<li>Thread 별로 Stack, Register를 가지고 있다.<blockquote>
<p>이부분 좀더 자세히 예를 들어 설명하자면
Heap에는 Java new, 객체(ex. Array,ArrayList)의 주소값을 갖고있는 변수가 들어간다
Static에는 말그대로 정적변수 그리고 8가지 원시타입이 들어간다.
Code도 말그대로 코드 관련된 값들이 들어가게된다.</br></p>
</blockquote>
</li>
<li><em>즉*</em>,  다른 Thread가 Heap, Static영역의 값 접근 방법을 알려주면 Thread끼리는 이러한 값들을 공유할수 있다.  </br>
반면에,  Registers, Stack에는 쓰레드 별로 갖고있는 지역변수에 대한 값을 가지고 있는데 이러한 값은 공유할수 없다는 말이된다.</li>
</ul>
<h1 id="3-process-와-thread의-차이">3. Process 와 Thread의 차이</h1>
<table>
<thead>
<tr>
<th align="left">Process</th>
<th align="left">Thread</th>
</tr>
</thead>
<tbody><tr>
<td align="left">프로그램이 실행하기 위한 모든 자원들을 개별적으로 가지고 있어 무겁다</td>
<td align="left">개별적으로 분리가 필요한 최소한의 자원들만 가져 LWP(Light Weight Process)라고도 하는 경량 process</td>
</tr>
<tr>
<td align="left">process별로 자체 메모리를 갖는다</td>
<td align="left">process내의 다른 thread와 메모리를 공유한다.</td>
</tr>
<tr>
<td align="left">개별 메모리로 인해 process 간 통신이 느리다.</br> process간 통신을 위해서는 OS에서 제공하는 다양한 통신 기술을 이용해야 한다.</td>
<td align="left">공유 메모리를 이용한 직접 통신이 가능해 thread 간 통신이 빠르다.</td>
</tr>
<tr>
<td align="left">Multi process 지원 시스템에서는 process context switching시 이전 process의 메모리 및 스택 정보를 storage에 저장하는 swapping 이 발생할 수 있으며, 이는 메모리에 있던 정보르 storage에 옮기거나 storage에 저장된 정보를 메모리에 올리는 작업이 수행되므로 비용이 많이 든다</td>
<td align="left">thread 간 context 전환은 공유 메모리로 인해 비용이 저렴하다.</td>
</tr>
<tr>
<td align="left">구성 요소에 대한 여러 process가 있는 application은 메모리가 부족할 때 더 나은 메모리 활용도를 제공할 수 있다.</br> Application의 비활성 process에 낮은 우선순위를 할당할 수 있다. 그러면 이 유휴 process는 storage로 swapping될  수 있다.</td>
<td align="left">메모리가 부족한 경우 Multi-threaded application은 메모리 관리를 위한 어떠한 조항도 제공하지 않는다.</td>
</tr>
<tr>
<td align="left"><br></td>
<td align="left"></td>
</tr>
</tbody></table>
<h1 id="4-single-vs-multi-thread">4. Single vs Multi Thread</h1>
<blockquote>
<p>단편적으로 생각하면 Single이나 Multi나 한 Process가 일을 하는 것이기 때문에 어느쪽이나 효율이 똑같다고 생각할수도 있다. 게다가 Multi Process는 Context Switching에 대한 비용도 있다.</p>
</blockquote>
<h4 id="그렇다면-multi-thread가-왜-좋을까-2가지-이유가-있다">그렇다면 Multi Thread가 왜 좋을까 2가지 이유가 있다.</h4>
<ol>
<li><p>프로세서의 활동을 극대화
 단편적으로 생각하면 Multi나 Single이나 Single Processer에서는 같다고 생각할 수 있지만 코드 영역에서는 한 Thread가 일을 마치면 Sleep 상태에 들어간다. Multi Thread는 그 사이의 놀고 있는 Process에 대한 활동을 극대화할수있다.</p>
</li>
<li><p>하나의 프로세스를 다수의 실행 단위로 구분하여 자원 공유</p>
</li>
</ol>
<br>
<br><br><br>

<h4 id="이정도로-thread에-대한-개요를-마치고-다음-게시물-부터는-java코드를-통해서-공부해나갈-계획입니다">이정도로 Thread에 대한 개요를 마치고 다음 게시물 부터는 Java코드를 통해서 공부해나갈 계획입니다.</h4>
]]></description>
        </item>
    </channel>
</rss>