>Java >java지도 시간 >Java 동기화 잠금의 샘플 코드 공유(동기화됨)

Java 동기화 잠금의 샘플 코드 공유(동기화됨)

黄舟
黄舟원래의
2017-03-29 10:40:221847검색

이 글에서는 주로 Java 동기화 잠금(동기화)에 대한 자세한 설명과 예시를 소개합니다. 필요한 친구는

Java 동기화 잠금(동기화) 자세한 설명과 예시를 참고하세요. 🎜>

Java의 각 스레드에 CPU가 할당하는 타임 슬라이스는 무작위이며 Java의 많은 스레드가 동일한 리소스를 공유합니다. 예를 들어 기차표를 판매할 때 기차표는 확실하지만 기차표를 판매하는 창구는 다음과 같습니다. 각 창은 스레드와 동일합니다. 매우 많은 스레드가 모든 기차표의 리소스를 공유합니다. 두 개의 스레드가 한 시점에 동시에 이 리소스를 사용하면 그들이 꺼내는 열차표가 동일(동일 좌석 번호)되므로 승객에게 문제가 발생합니다. 예를 들어, 다음 프로그램은

package com.pakage.ThreadAndRunnable; 
 
public class Runnable_demo implements Runnable{ 
  private int ticket=10; 
  public Runnable_demo(){    
  } 
  @Override 
  public void run() { 
    for(int i=0;i<20;i++){ 
        if(this.ticket>0){ 
          //休眠1s秒中,为了使效果更明显,否则可能出不了效果 
          try { 
            Thread.sleep(1000); 
          } catch (Exception e) { 
            e.printStackTrace(); 
          } 
          System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); 
        } 
       
    } 
  } 
   
   public static void main(String args[]){ 
     Runnable_demo demo=new Runnable_demo(); 
     //基于火车票创建三个窗口 
     new Thread(demo,"a").start(); 
     new Thread(demo,"b").start(); 
     new Thread(demo,"c").start(); 
   } 
   
}

프로그램 실행 결과:

Java 동기화 잠금의 샘플 코드 공유(동기화됨)

창 c와 창 b 모두 10장의 티켓을 판매한 것을 확인할 수 있습니다. 0번과 -1번 창구는 각각 a 창구와 b 창구에서 판매됐다. 이러한 상황이 발생한 이유는 1입니다. c 스레드와 b 스레드의 티켓=10일 때 c 스레드가 10번 티켓을 꺼낸 후 아직 티켓이 오지 않아 1만큼 줄어들고 b 스레드가 티켓을 가져옵니다. 이때 티켓은 여전히 ​​10입니다. ; 2. ticket=1일 때 스레드 c는 티켓 1번을 꺼냅니다. 티켓이 오기 전에 1씩 감소합니다. 스레드 a와 b는 if

판정문 이 때 티켓이 1씩 감소하고 스레드 a와 b가 티켓을 얻으면 0번과 -1번 티켓을 얻습니다.

위 상황을 어떻게 바꿀 수 있나요?

스레드가 기차표 리소스를 사용하려고 하면 스레드에 잠금을 부여하고 해당 작업이 수행될 때까지 기다립니다. 마무리하고 이 리소스를 사용하려는 다른 스레드에 잠금을 부여하세요. 이렇게 하면 위의 상황이 발생하지 않습니다. 이 잠금 기능을 구현하려면 동기화 키워드를 사용해야 합니다.

1. 동기화 방법을 사용하여 위의 예를 다음과 같이 변경합니다.

package com.pakage.ThreadAndRunnable; 
 
public class Runnable_demo implements Runnable{ 
  private int ticket=10; 
  public Runnable_demo(){    
  } 
  @Override 
  public void run() { 
    for(int i=0;i<20;i++){ 
        if(this.ticket>0){ 
          //休眠1s秒中,为了使效果更明显,否则可能出不了效果 
          try { 
            Thread.sleep(1000); 
          } catch (Exception e) { 
            e.printStackTrace(); 
          } 
          this.sale(); 
        } 
       
    } 
  } 
   
  public synchronized void sale(){ 
    if(this.ticket>0){ 
      System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); 
    } 
  } 
   
   public static void main(String args[]){ 
     Runnable_demo demo=new Runnable_demo(); 
     //基于火车票创建三个窗口 
     new Thread(demo,"a").start(); 
     new Thread(demo,"b").start(); 
     new Thread(demo,"c").start(); 
   } 
   
}

프로그램의 출력 결과는 다음과 같습니다.

2. 동기화 블록을 사용하여 위의 예를 수정합니다.

Java 동기화 잠금의 샘플 코드 공유(동기화됨)

package com.pakage.ThreadAndRunnable; 
 
public class Runnable_demo implements Runnable{ 
  private int ticket=10; 
  public Runnable_demo(){    
  } 
  @Override 
  public void run() { 
    for(int i=0;i<20;i++){ 
      <span style="color:#ff0000">synchronized</span>(this){ 
        if(this.ticket>0){ 
          //休眠1s秒中,为了使效果更明显,否则可能出不了效果 
          try { 
            Thread.sleep(1000); 
          } catch (Exception e) { 
            e.printStackTrace(); 
          } 
          System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); 
        } 
      } 
       
    } 
  } 
   
   public static void main(String args[]){ 
     Runnable_demo demo=new Runnable_demo(); 
     //基于火车票创建三个窗口 
     new Thread(demo,"a").start(); 
     new Thread(demo,"b").start(); 
     new Thread(demo,"c").start(); 
   } 
   
}

프로그램의 출력 결과:

위 내용은 Java 동기화 잠금의 샘플 코드 공유(동기화됨)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.