자바 기반 학습 (팔) - 멀티 스레드

이해 스레드

프로세스는 메모리에서 실행되는 응용 프로그램, 시스템은 프로세스 실행에서 생성되는 프로그램, 프로세스의 종료를 실행합니다.

쓰레드가 실행 부 공정이며, 현재의 처리는 프로그램을 실행하는 과정에서, 적어도 하나 개의 스레드에 대한 책임이있다.

다중 스레드가 동시에 실행 (여러 작업을 수행하는 시간의 같은 기간)이 특징입니다, 더 높은 CPU 사용을 허용, 실제로 실행 속도를 증가하지 않지만, 운영 효율성을 향상시킬 수 있습니다.

스레드 스케줄링 정보, 시분할 스케줄링 및 선점 스케줄링으로 구분.

  • 선점 스케줄링 모드, 우선 순위가 높은 우선 순위의 스레드 우선 순위를 사용 CPU의 스레드를 설정합니다.
  • 시간 공유 예약을 모든 스레드가 CPU를 사용하여 교대로, 시간의 평균 할당 각 스레드는 CPU를 차지한다.

멀티 스레딩은 1.Java 달성

자바 멀티 스레딩은 두 가지 방법으로 구현 :

  1. Thread 클래스를 상속하고 실행하는 스레드 객체를 생성, 실행 방법을 재정의합니다.
  2. Runable 정의 된 인터페이스의 구현 클래스와 실행 방법 오버라이드 인터페이스 (실행 스레드). 실행의 스레드 만 및 실행에 전달 Thread 오브젝트로서 run () 메소드를 구현 포함하는 실행 가능한 클래스.

Thread 클래스는 장점을 상속보다 Runnable를 구현 :

  1.  같은 프로그램 코드에 대한 여러 스레드가 같은 자원을 공유 할 수 있습니다.
  2. 자바 단일 상속의 한계를 방지하려면.
  3.  작동 디커플링, 코드가 여러 스레드에 의해 공유 될 수 있으며, 프로그램의 견고성을 향상하고, 독립적 인 코드를 스레드.
  4.  스레드 풀은 직접적으로 상속 스레드 클래스로, 스레드에 Runable 또는 호출 가능 클래스를 달성 할 수있다.

생성자 :

  • 공공 스레드 () : 새로운 Thread 객체를 할당합니다.
  • 공공 스레드 (문자열 이름) : 새 스레드가 지정된 객체의 이름을 지정합니다.
  • 공공 스레드 (Runnable를 대상) : 지정된 대상으로 새로운 Thread 객체를 할당합니다.
  • 공공 스레드 (Runnable를 대상 문자열 이름) : 지정된 목표를 가진 새로운 Thread 객체를 할당하고 이름을 지정합니다.

일반적인 방법 :

  • 공공 문자열 getName은 () : 현재의 thread의 이름을 가져옵니다.
  • 공공 무효 시작 () : 실행을 시작하는이 스레드가 발생, 자바 가상 머신이 스레드의 run 메소드를 호출합니다.
  • 공공 무효 실행 () : 여기에 정의 된 코드를 실행하기 위해이 스레드 임무.
  • 공공 정적 무효 수면 (긴 밀리) : 스레드가 현재 일시 밀리 지정된 수의 실행 (일시적으로 실행을 정지).
  • 공공의 고정 나사 currentThread는 () : 현재 실행중인 스레드 객체에 대한 참조가 반환.

다음 코드는 구현 프로세스를하여 이해하기 :

// THEAD 달성 상속 
클래스를 MyThead (가) 확장 스레드 {
     공공 MyThead (문자열 이름) {
         슈퍼 (이름); 
    } 
    @Override 
    공공  무효 실행 () { 
        에서 System.out.println ( "나는 스레드입니다"+ getName ()); 
    } 
} 


공공  클래스 TestThread {
     공공  정적  무효 메인 (문자열 []에 args) {
         // 스레드 객체 생성 
        MyThead MT = 새로운 새로운 MyThead ( "M" );
         //는 새로운 스레드 열 
        mt.start를 (); 
        에서 System.out.println을 ("나는 메인 스레드이다" ) 
    } 
}
// Runnable를 달성의 run 메소드 오버라이드 (override) 
클래스를 MyRunable 구현 의 Runnable { 
    @Override 
    공공  무효 실행 () { 
        에서 System.out.println이 ( + "나는 스레드입니다" ;.는 Thread.currentThread () getName ()) 
    } 
} 
공공  클래스 TestRunable {
     공공  정적  무효 메인 (문자열 []에 args) {
         // MyRunable 객체를 생성 
        MyRunable 씨의 = 새로운 새로운 MyRunable을 ();
         //는 스레드 객체를 생성 
        스레드 T는 = 새로운 새로운 (씨의 "T"스레드를 )
         // 스레드 실행
         t.start ();
        에서 System.out.println ( "나는 메인 스레드입니다" ); 
    } 
}

2. 스레드 동기화

여러 스레드가 스레드에서 자원을 같은 리소스에 액세스하고 수정 사용하는 경우, 스레드 안전 문제가 발생할 것입니다.

// Runnable를 달성의 run 메소드 오버라이드 (override) 
클래스를 MyRunable 구현 실행 가능한 {
     개인  INT의 A = 10 ; 
    @Override 
    공공  무효 실행 () {
         그동안 (A> 0 ) { 
            
            은 try { 
                에 Thread.sleep ( 10 ); 
            } 캐치 (예외 : InterruptedException E) { 
                e.printStackTrace (); 
            } - = 1이다. ] 
            에서 System.out.println ( . "스레드"+는 Thread.currentThread () getName () + " (A)의 연산 값"+ a); 
        } 

    } 
}
공공  클래스 TestRunable {
     공공  정적  무효 메인 (문자열 []에 args) {
         // 생성 객체 MyRunable 
        씨 =의 MyRunable 새로운 새로운 MyRunable ();
         // 스레드 객체를 생성 
        스레드가 = T1 새 새 (씨의 "T1"을 스레드를 ) 
        스레드 T2 = 새로운 새로운 (씨의 "T2"스레드 ) 
        스레드 T3 = 새로운 새로운 스레드 (씨의 "T3" );
         // 스레드 실행 
        t1.start (); 
        t2.start (); 
        t3.start (); 

    } 
}

복수의 스레드를 동작 변수 있기 때문에, 비정상 값을 생성하는 단계 (-1 발생 안된다).

스레드 안전 문제는 작동에 의한 전역 변수를 수정하는 여러 스레드에 의해 발생, 당신은 스레드 동기화를 사용해야합니다.

동기화 원리 스레드 :

자원을 운영 스레드가 다른 스레드가 동작하도록 허용하지 않을 경우, 데이터의 동기화를 보장합니다.

자바는 스레드 동기화를 구현하는 세 가지 방법을 제공합니다.

  • 동기화 코드 블록 : 동기화 된 키워드가 블록의 과정에서 사용할 수 있으며, 블록은 코드에 단독으로 액세스를 추가합니다.
  • 동기화 방법 : 수정 방법을 동기화 사용. 이 방법의 구현 스레드는 다른 스레드가 차단된다.

  • 잠금 잠금 : 또한 동기화 잠금, 잠금 장치로 알려져 있으며 방법의 잠금을 해제.

동기화 블록 :

// 实现Runnable를,重写실행方法의 
클래스 MyRunable는 구현 의 Runnable {
     개인  INT의 A = 10 ;
    // 同步锁 
    개체 잠금 = 개체 (); 
    @Override 
    공공  무효 실행 () {
         동안 ( 사실 ) {
             동기화 (잠금) {
                 경우 (A> 0 ) {
                     시도 { 
                        Thread.sleep를 ( 50 ); 
                    } 잡기  (예외 : InterruptedException 전자) {
                        ) (e.printStackTrace을; 
                    } - = 1이다. ] 
                    에서 System.out.println ( . "스레드"+는 Thread.currentThread () getName () + " (A)의 연산 값"+ A); 

                } 

            } 
        } 
    } 
} 
공용  클래스 TestRunable {
     공공  정적  무효 메인 (문자열 []에 args) {
         // 생성 객체 MyRunable 
        씨 =의 MyRunable 새로운 새로운 MyRunable ();
         //이 스레드 객체를 생성 
        스레드 = T1 새로운 새로운 스레드를 (씨의 "T1" );
        스레드 T2 =  미스터 (스레드 "T2"); 
        스레드 T3 =  스레드 (씨, "T3" );
        // 运行线程
        t1.start (); 
        t2.start (); 
        t3.start (); 

    } 
}

동기화 방법 :

//实现Runnable,重写run方法
class MyRunable implements Runnable{
    private int a = 10;
    @Override
    public void run(){
        while (true) {
            method1();
        }
    }
    //同步方法
    public synchronized void method1(){
        if (a > 0){
            try{
                Thread.sleep(50);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            a -= 1;
            System.out.println("线程"+Thread.currentThread().getName()+"操作了a,a的值为"+a);

        }
    }
}
public class TestRunable {
    public static void main(String[] args){
        //创建 MyRunable对象
        MyRunable mr = new MyRunable();
        //创建线程对象
        Thread t1 = new Thread(mr,"t1");
        Thread t2 = new Thread(mr,"t2");
        Thread t3 = new Thread(mr,"t3");
        //运行线程
        t1.start();
        t2.start();
        t3.start();

    }
}

Lock锁包含两个方法:

  • public void lock() :加同步锁。
  • public void unlock() :释放同步锁。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//实现Runnable,重写run方法
class MyRunable implements Runnable{
    private int a = 10;
    //同步锁
    Lock lock = new ReentrantLock();
    @Override
    public void run(){
        while (true){
            //加锁
            lock.lock();
            if (a > 0){
                try{
                    Thread.sleep(20);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                a -= 1;
                System.out.println("线程"+Thread.currentThread().getName()+"操作了a,a的值为"+a);

            }
            //释放锁
            lock.unlock();
        }
    }
}
public class TestRunable {
    public static void main(String[] args){
        //创建 MyRunable对象
        MyRunable mr = new MyRunable();
        //创建线程对象
        Thread t1 = new Thread(mr,"t1");
        Thread t2 = new Thread(mr,"t2");
        Thread t3 = new Thread(mr,"t3");
        //运行线程
        t1.start();
        t2.start();
        t3.start();

    }
}

3.线程状态

  • NEW:线程创建未启动。
  • Runnable:可运行。
  • Blocked:锁阻塞。当一个线程获得同步锁时,其他线程会被阻塞,直到获得同步锁。
  • Waiting:无限等待。当一个线程进入Waiting状态后,会无限等待,直到其他线程调用notify或者notifyAll方法唤醒(线程通信)。
  • TimedWaiting:计时等待当一个线程调用sleep方法时,程序会进入计时等待,直到时间结束。
  • Teminated:被终止。run方法未正常退出而死亡。

温馨提示

  • 如果您对本文有疑问,请在评论部分留言,我会在最短时间回复。
  • 如果本文帮助了您,也请评论关注,作为对我的一份鼓励。
  • 如果您感觉我写的有问题,也请批评指正,我会尽量修改。

 

추천

출처www.cnblogs.com/lyxdw/p/11668744.html