메인 스레드: 메인 메소드를 실행하는 스레드를 메인 스레드라고 합니다
싱글 스레드 프로그램: 프로그램은 mani
부터 위에서 아래로 순차적으로 실행됩니다. 프로그램이 메인 메소드에서 실행되기 시작합니다. JVM이 메인 메소드를 실행하면 운영 체제는
CPU에 대한 실행 경로를 엽니다. CPU는 이 경로를 통해 메인 메소드를 실행할 수 있습니다.
이 경로는 메인 스레드라는 이름을 가집니다.
스레드 메소드를 생성합니다. 1. Thread 클래스 상속
구현 단계:
1. Thread 클래스의 하위 클래스 생성
2. Thread 클래스의 run 메서드를 다시 작성하고 스레드의 작업 설정
3. Thread 클래스의 하위 클래스 객체 생성
4. Thread 클래스의 start 메소드를 호출하여 새 스레드를 시작하고, run 메소드
를 실행하여 스레드가 실행을 시작하도록 합니다. Java 가상 머신은 스레드의 run 메소드를 호출합니다.
결과적으로 두 개의 스레드가 동시에 실행됩니다. 즉, 현재 스레드(메인 스레드)와 다른 스레드(run 메서드를 실행하는 스레드)입니다.
스레드를 여러 번 시작하는 것은 불법입니다. 특히 스레드 실행이 끝나면 다시 시작할 수 없습니다.
인쇄된 결과에는 무작위성이 있습니다.
스레드 두 개를 열고 CPU에 맞는 것을 선택하세요.
원하는 사람이 모두 처형되므로 무작위성이 있습니다.
1 public class MyThread extends Thread{ 2 /* 3 * 2.重写Thread类中的run方法,设置线程的任务 4 * 开启这个线程要干什么事情 5 */ 6 @Override 7 public void run() { 8 for (int i = 0; i < 50; i++) { 9 System.out.println("run..."+i);10 }11 }12 }13 public static void main(String[] args) {14 //3.创建Thread类的子类对象15 MyThread mt = new MyThread();16 //mt.run();//不会开启线程,还是单线程程序17 //4.调用Thread类中的start方法开启一个新的线程,执行run方法18 mt.start();19 20 new MyThread().start();21 22 for (int i = 0; i < 50; i++) {23 System.out.println("main..."+i);24 }25 }
스레드 이름:
메인 스레드: " main"
열려 있는 다른 스레드의 이름: "Thread-0", "Thread-1"....
스레드 이름 가져오기
1. Thread 클래스의 getName 메소드
String getName()은 스레드 이름을 반환합니다. 스레드.
2. 현재 실행 중인 스레드를 얻기 위한 Thread 클래스의 정적 메서드
정적 Thread currentThread()는 현재 실행 중인 스레드 개체에 대한 참조를 반환합니다.
스레드 이름 설정:
1. Thread 클래스의 setName(문자열 이름) 메소드
void setName(문자열 이름)은 스레드 이름을 매개변수 이름과 동일하게 변경합니다.
2. 하위 클래스에 매개변수화된 구성을 추가하고, 상위 클래스 Thread 클래스의 매개변수화된 생성자를 호출하고, 스레드 이름을 전달하고, 상위 클래스에서 스레드 이름을 지정하도록 합니다(아버지가 아들 이름을 지정하도록 함)
Thread(문자열 이름 )은 새로운 Thread 객체를 할당합니다.
스레드 모드 생성 - Runnable 인터페이스 구현
구현 단계:
1. Runnable 인터페이스의 구현 클래스 생성
2. Runnable 인터페이스의 run 메서드를 재정의하고 스레드 작업 설정
3. 구현 클래스 생성 Runnable 인터페이스의 객체
4. Thread 클래스 객체를 생성하고 생성자
Thread(Runnable 대상)에 Runnable 인터페이스의 구현 클래스를 전달하여 새 Thread 객체를 할당합니다.
5. Thread 클래스의 start 메소드를 호출하여 스레드를 시작하고 run 메소드를 실행합니다.
Runnable 구현의 이점
1. 클래스가 Thread 클래스를 상속하지 않고 다른 클래스를 상속하는 것을 방지합니다(단일 상속의 한계).
2. 스레드 작업 설정과 시작 스레드가 분리되어 확장성이 향상됩니다.
구현 클래스의 역할은 스레드 작업을 설정하는 것입니다.
스레드 클래스의 역할: 스레드 시작
이점: 다양한 구현 클래스 전달, 구현 클래스 다시 쓰는 방법이 다르므로 다른 메서드를 호출할 수 있습니다
스레드의 익명 내부 클래스가 사용됩니다
익명: 이름 없음
내부 클래스: 다른 클래스 내부에 작성된 클래스(멤버 위치: 멤버 내부 클래스, 로컬 위치(메서드 내): 로컬 내부 클래스)
익명 내부 클래스 형식:
새 상위 클래스/인터페이스(){
상위 클래스/인터페이스의 메서드 재정의;
};
다중 스레드 상위 클래스:
Thread
Runnable
1 new Thread(){2 //重写run方法,设置线程任务3 @Override4 public void run() {5 for (int i = 0; i < 20; i++) {6 System.out.println(Thread.currentThread().getName()+":"+i);7 }8 }9 }
The 위의 힙 코드는 하위 클래스를 생성하고 상위 클래스 메서드를 다시 작성하는 프로세스입니다.
다음과 동일: new MyThread().start()
프로그램에는 스레드 안전 문제가 있습니다. 중복 티켓과 존재하지 않는 티켓이 판매됩니다
해결 방법:
첫 번째 방법: 동기화된 코드 블록을 사용할 수 있습니다
동기화된(잠금 개체) {
보안 문제를 일으키는 코드
공유 데이터에 액세스하는 코드
}
참고:
여러 스레드에서 사용되도록 보장되어야 합니다. is the same lock object
//멤버 위치에 lock 객체 생성(고유함 보장)
1 Object obj = new Object(); 2 3 @Override 4 public void run() { 5 //让卖票重复执行 6 while(true){ 7 8 * 同步代码块 9 * 程序会频繁的判断锁,获取锁,释放锁,所以会降低速度10 11 synchronized (obj) {12 if(ticket>0){13 //为了提高安全问题的概率,让程序睡眠14 try {15 Thread.sleep(10);16 } catch (InterruptedException e) {17 e.printStackTrace();18 }19 //卖票ticket--20 System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");21 }22 }23 }24 }
프로그램에 스레드 안전 문제가 있습니다: 중복 티켓과 존재하지 않는 티켓이 판매됩니다
해결 방법:
두 번째 메소드: 동기화된 메소드
사용 단계:
1. 보안 문제가 발생할 수 있는 코드를 메소드로 추출
2. 메소드에 동기화된 키워드 추가
수정자 동기화 반환 값 유형 메소드 이름(매개변수) {
보안이 적용된 가능한 코드 Issues;
공유 데이터에 액세스하는 코드;
}
동기화 방법에 사용되는 잠금 개체는 무엇입니까?
이 클래스 개체는 무엇에 사용됩니까 new RunnableImpl()-->이것을 호출하세요
정적 동기화 방법, 어떤 잠금 객체가 사용되나요?
사용되는 것은 이 클래스 객체의 클래스 속성(리플렉션)입니다
RunnableImpl.class
1 *@Override 2 public void run() { 3 //让卖票重复执行 4 while(true){ 5 payTicket2(); 6 } 7 } 8 9 10 * 静态的同步方法11 12 public static synchronized void payTicket2(){13 synchronized (RunnableImpl.class) {14 if(ticket>0){15 //为了提高安全问题的概率,让程序睡眠16 try {17 Thread.sleep(10);18 } catch (InterruptedException e) {19 e.printStackTrace();20 }21 //卖票ticket--22 System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");23 }24 }25 }26 27 28 29 * 抽取出一个同步方法30 * 快捷键:alt+shift+m31 32 public ynchronized void payTicket1() {33 synchronized (this) {34 //System.out.println(this);//cn.itcsat.demo10.RunnableImpl@6706435 if(ticket>0){36 //为了提高安全问题的概率,让程序睡眠37 try {38 Thread.sleep(10);39 } catch (InterruptedException e) {40 e.printStackTrace();41 }42 //卖票ticket--43 System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");44 }45 }46 }
程序出现了线程安全问题:卖了重复的票和不存在的票
*
* 解决方案:
* 第三种方式:使用Lock接口,JDK1.5之后出现的
*
* java.util.concurrent.locks.Lock接口
* 方法:
* void lock() 获取锁。
* void unlock() 释放锁。
* 接口的实现类:ReentrantLock
*
* 实现步骤:
* 1.在成员位置创建一个Lock接口的实现类对象ReentrantLock
* 2.在可能出现线程安全问题的代码前,调用lock方法获取锁
* 3.在可能出现线程安全问题的代码后,调用unlock方法释放锁
*
*1.在成员位置创建一个Lock接口的实现类对象ReentrantLock
Lock l = new ReentrantLock();
1 @Override 2 public void run() { 3 //让卖票重复执行 4 while(true){ 5 //2.在可能出现线程安全问题的代码前,调用lock方法获取锁 6 l.lock(); 7 if(ticket>0){ 8 //为了提高安全问题的概率,让程序睡眠 9 try {10 Thread.sleep(10);11 //卖票ticket--12 System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");13 } catch (InterruptedException e) {14 e.printStackTrace();15 }finally {16 //3.在可能出现线程安全问题的代码后,调用unlock方法释放锁17 l.unlock(); 18 }19 }20 }
위 내용은 스레드, 스레드 생성 예제 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!