> Java > java지도 시간 > 본문

스레드에 대한 Java 기본 이해

零下一度
풀어 주다: 2017-07-18 17:54:20
원래의
1258명이 탐색했습니다.

멀티스레딩을 이해하기 전에 먼저 프로세스와 스레드에 대한 이해가 필요합니다.

프로세스는 QQ, 360 Butler 등 컴퓨터에서 독립적인 각 프로그램의 실행 활동을 의미합니다.

스레드는 멀티스레딩 내의 실행 경로입니다. 프로그램에서 동시에 여러 스레드를 실행할 수 있으면 이 프로그램이 멀티스레딩을 지원한다고 말합니다. Thunder 다운로드 소프트웨어는 동시에 여러 작업을 다운로드할 수 있습니다.

멀티스레딩이란 무엇인가요?

멀티 스레딩은 멀티 태스킹으로 이해될 수 있습니다. 프로그램은 동시에 여러 작업을 실행합니다. 각 작업은 일반적으로 여러 스레드를 실행할 수 있는 프로그램을 멀티 스레드 프로그램이라고 합니다. .

멀티스레딩이 왜 필요한가요?

멀티 태스킹 동시 작업 방법인 멀티 스레딩은 다음과 같은 특징을 가지고 있습니다.

응용 프로그램 응답 향상

컴퓨터 CPU 활용도 향상

프로그램 구조 향상. 길고 복잡한 프로세스는 여러 스레드로 나누어 여러 개의 독립적이거나 반독립적인 실행 부분이 될 수 있습니다. 이러한 프로그램은 이해하고 수정하기가 더 쉽습니다.

멀티 스레드 프로그램을 만드는 방법 및 단계:

방법 1: Thread 클래스를 사용하여 스레드 만들기

1) Thread 클래스에서 상속되는 클래스 작성

2) 실행 메서드 재정의 //이 메서드 거기에 있는 콘텐츠가 실행될 콘텐츠입니다

3) 이 사용자 정의 Thread 클래스를 새로 만듭니다

4) 이 스레드를 시작하려면 start 메서드를 호출합니다. (start 메서드에는 두 가지 기능이 있는데, 하나는 스레드를 시작하는 것이고, 다른 하나는 run 메소드를 호출하는 것입니다)

public class Test12 {public static void main(String[] args) {
        ThreadDemo t = new ThreadDemo();
        t.start();// 啓動ThreadDemo t2 = new ThreadDemo();
        t2.start();

        ThreadDemo t3 = new ThreadDemo();
        t3.start();for (int i = 0; i < 20; i++) {
            System.out
                    .println("线程" + Thread.currentThread().getName() + "正在运行");
        }
    }
}class ThreadDemo extends Thread {
    @Overridepublic void run() {for (int i = 0; i < 200; i++) {
            System.out
                    .println("线程" + Thread.currentThread().getName() + "正在运行");
            ;
        }
    }

}
로그인 후 복사

요점 요약:

새 스레드에서 코드 조각을 실행하려면 이 코드를 클래스의 run 함수에 배치해야 하며, 클래스는 ran 함수가 있는 곳은 Thread 클래스 Class의 하위 클래스입니다

다르게 말하면, 멀티스레딩을 구현하려면 Threa 클래스를 상속하는 하위 클래스를 작성하고 해당 실행 메소드를 다시 작성해야 합니다

시작하려면 스레드를 생성하는 경우 Thread 하위 클래스 개체의 run 메서드를 호출하지 않고 Thread 하위 클래스 개체(Thread 클래스에서 상속됨)의 start 메서드를 호출합니다. 이 메서드는 새 스레드를 생성하고 하위 클래스 개체에서 run 메서드를 실행합니다. 스레드의 코드 세그먼트가 run 메소드에 배치되므로 메소드가 실행된 후 스레드가 종료됩니다

public class Test {public static void main(String[] args) throws InterruptedException {
                    ThreadDemo t=new ThreadDemo();
                    t.start();                    while(true){
                        System.out.println("这是线程一输出的内容");
                        Thread.sleep(10);
                    }
                }
            }            
            class ThreadDemo extends Thread{public void run() {for (int i = 0; i < 50; i++) {
                        System.out.println("这是线程二输出的内容");
                    }
                }
            }
로그인 후 복사

//例子,创建三个线程,和主线程同时运行public class Test2 {public static void main(String[] args) {
                MyThread t1=new MyThread();
                t1.start();
                
                MyThread t2=new MyThread();
                t2.start();
                
                MyThread t3=new MyThread();
                t3.start();                    for (int i = 0; i < 200; i++) {
                    System.out.println("主线程"+Thread.currentThread().getName()+"正在运行");
                }    
            }    
        }
로그인 후 복사

方法二:使用Runable接口实现多线程

1)自定义一个类,implements Runnable接口

2)重写run方法

3)new出来这个自定的类//该类对象会作为Thread类构造函数的参数

4)new出Thread类

5)调用start方法

继承Thread类创建线程和实现Ruanble接口创建线程的区别

使用 Runable 接口创建多线程

1.适合多个相同的程序代码去处理同一资源的情况 把虚拟CPU (线程)同程序的代码 数据有效分离,较好的体现了面象对象

2.可以避免java单继承带来的局限 例如:当我们将已经继承了某类的一个类的子类放入多线程中,由于不能同时继承两个类,所以

什么情况下,不能采用继承Thread的方式,只好通过实现Ruanable?

1.当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runable接口类的实例

2.事实上,几乎所有的多线程都可以用Runnable接口方式

三、自定义线程

1) 线程的名字,一个运行中的线程总是有名字的,名字有两个来源,一个是虚拟机自己给的名字,

一个是你自己的定的名字。在没有指定线程名字的情况下,虚拟机总会为线程指定名字,并且主线程的名字总是mian,非主线程的名字不确定。

//Thread(String name) 可以在构造线程的时候,直接传入名字

//getName () 可以得到线程的名字

2) 获取当前线程的对象的方法是:Thread.currentThread();

3) 在上面的代码中,只能保证:每个线程都将启动,每个线程都将运行直到完成。一系列线程以某种顺序启动并不意味着将按该顺序执行。

对于任何一组启动的线程来说,调度程序不能保证其执行次序,持续时间也无法保证。

4) 当线程目标run()方法结束时该线程完成

5) 一旦线程启动,它就永远不能再重新启动。只有一个新的线程可以被启动,并且只能一次。一个可运行的线程或死线程可以被重新启动。

//t1.start(); 即这个操作只能一次,如果多次,将引发 java.lang.IllegalThreadStateException

class MyThread extends Thread{public void run() {for (int i = 0; i < 20000; i++) {
                    System.out.println("线程"+Thread.currentThread().getName()+"正在运行");
                }
            }
}
로그인 후 복사

四、线程的状态

新建 (Born) : 新建的线程处于新建状态

就绪 (Ready) : 在创建线程后,start() 方法被调用它将处于就绪状态

运行 (Running) : 线程在开始执行时(run)进入运行状态

睡眠 (Sleeping) : 线程的执行可通过使用 sleep() 方法来暂时中止。在睡眠结束后,线程将进入就绪状态

等待 (Waiting) : 如果调用了 wait() 方法,线程将处于等待状态。用于在两个或多个线程并发运行时。

挂起 (Suspended) : 在临时停止或中断线程的执行时,线程就处于挂起状态。 //suspend() 已过时,有固定的死锁倾向

恢复 (Resume) : 在挂起的线程被恢复执行时,可以说它已被恢复。

阻塞 (Blocked) – 在线程等待一个事件时(例如输入/输出操作),就称其处于阻塞状态。

死亡 (Dead) – 在 run() 方法已完成执行或其 stop() 方法被调用之后,线程就处于死亡状态。 //stop 方法有两个重载,均已过时,有固定的不安全性

****

Java 中的线程优先级是在 Thread 类中定义的常量

NORM_PRIORITY : 值为 5

MAX_PRIORITY : 值为 10

MIN_PRIORITY : 值为 1

缺省优先级为 NORM_PRIORITY

****

有关优先级的方法有两个:

final void setPriority(int newp) : 修改线程的当前优先级

final int getPriority() : 返回线程的优先级

五、sleep 和 yield 的区别

1) sleep是Thread类的一个静态方法,该方法会让当前正在 执行的线程暂停执行,从而将执行机会让给其他线程执行。

sleep(long mills)参数指定当前线程暂停执行的时间,经过这段阻塞时间后,该线程会进入就绪状态,等候线程调度器的调度

sleep方法声明抛出了InterruptedException异常,所以调用sleep方法时要么在方法开始处抛出异常要么使用try{}..catch{}块进行捕获。

2) yield 方法只会给优先级相同或更高优先级的线程执行机会。yield不会将线程转入阻塞状态,只是强制当前线程进入就绪状态。

因此完全有可能某个线程调用yield方法暂停后,立即又获得处理器资源被执行。yield方法没有声明抛出任何异常。

// 通俗地说 yield()方法只是把线程的状态 由执行状态打回准备就绪状态

public void run() {for (int i = 0; i < 50; i++) {
        System.out.println(getName() + "--->" + i);if (i == 20) {
            Thread.yield();
            }
            }
            }public static void main(String[] args) {
                YieldThread t1 = new YieldThread("高级");
                t1.start();// 若当前线程优先级最高,那么即使调用了yield()方法,线程调度器又会将这个线程调度出来重新执行// t1.setPriority(Thread.MAX_PRIPORITY);YieldThread t2 = new YieldThread("低级");
                t2.start();
                t2.setPriority(Thread.MIN_PRIORITY);
                }
로그인 후 복사

 六、线程同步 synchronized

原理讲解:任何对象都有一个标志位.是0或1 程序执行到这里.会检查这个对象的标志位,如果是1,那么向下执行,同时将标志信置为0

如果标志位为0,则线程发生阻塞.一直等到标志位为1 标志位又叫锁旗标

synchronized 又叫锁定了监视器 一个线程可以再进入线程锁定临视器.就象蓝球运动员再拿到球一样。

class SaleThread2  implements Runnable{//static int ticket=1000;private int ticket;public SaleThread2(int ticket){this.ticket=ticket;
            }
            
            String lockStr="";//Object obj=new Object();public void run() {while(true){synchronized (lockStr) {  //锁 ,锁旗标if(ticket>0){try{
                                    Thread.sleep(10);    
                            }catch(Exception ex){
                                ex.printStackTrace();
                            }
                            
                            System.out.println("线程"+Thread.currentThread().getName() +"正在卖第"+ticket--+"张票");
                        }else{break;
                        }
                    }
                }    
            }
        }
로그인 후 복사

 

위 내용은 스레드에 대한 Java 기본 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!