사람들이 데려 갈 수없는이 세상에서 세 가지가 있습니다 : 첫 번째, 두 번째는 꿈에 숨겨진, 음식의 뱃속에 먹고, 세 책은 뇌에 읽기
멀티 스레딩 빠른 시작
1 스레드와 프로세스의 차이
시스템에서 실행중인 각 프로그램은 과정이다. 각 프로세스는 하나 개 이상의 스레드가 포함되어 있습니다. 스레드는 명령들의 세트, 또는 독립적으로 프로그램을 실행할 수있는 프로그램의 특정 부분 집합이다. 그래서 기본적으로 하나의 프로그램에서 여러 작업을 수행 할 책임이 경량 프로세스 스레드. 운영 체제에서 스케줄링 및 다중 스레드의 실행을 위해 일반적으로 책임.
프로그램의 속도를 실행에 대처하기 위해 백그라운드 작업으로 프로그램에서 오랜 시간을 차지할 수 스레드를 사용하여 같은 사용자 입력을 기다리는 같은 일부 작업의 실현을 가속화 할 가능성이 파일을 읽고, 쓰고, 네트워크 데이터를 전송 및 수신 스레드는 더 유용하다 . 이 경우 메모리 사용으로 등 몇 가지 귀중한 자원을 확보 할 수 있습니다.
운영 체제가 그들 사이를 전환 할 필요가 있기 때문에 많은 수의 스레드가 성능에 영향을 미칠 수 있다면, 더 많은 스레드가 더 많은 메모리 공간을 필요로, 스레드 정지는 프로그램 실행에 미치는 영향을 고려해야합니다. 일반적 모델 데이터 블록은 복수의 스레드 사이에서 공유되는 스레드는 교착 상태를 방지해야한다.
- 요약 :이 프로세스는 모든 스레드의 집합이고, 각 스레드의 실행 처리의 경로이다.
2. 왜 멀티 스레딩을 사용합니까?
(1) 다수의 스레드 수를 사용하여 프로그램의 응답 시간을 줄이고 . 단일 스레드 또는 장애물을 기다릴 필요가있는 경우, 프로그램은 마우스, 키보드 및 기타 작업에 응답하지 않는 원인이됩니다, 여러 스레드의 사용이 문제, 향상된 대화 형 프로그램을 해결할 수 있습니다.
(2) 프로세스, 스레드와 비교 생성 및 스위칭 오버 작은 메모리 공간 스레드 등 코드 세그먼트, 데이터 세그먼트를 공유하고 있기 때문에.
(3) 멀티 코어 CPU가 멀티 코어 컴퓨터 자체가 수행 할 수있는 능력이있는 단일 스레드, 당신은 다시 사용 할 수없는 컴퓨팅 리소스, 멀티 스레드 자원의 엄청난 낭비의 결과.
(4) 멀티 스레딩 할 프로그램의 구성을 간단하게 유지하기 위해 프로그램을 용이하게, 매우 복잡한 프로세스는 다수의 실행 스레드로 나눌 수있다.
3, 멀티 스레드 응용 프로그램 시나리오?
- A : 주요 효율성을 향상시킬 수있는 멀티 스레드 프로그램을 구현.
- 예 : 천둥 멀티 스레드 다운로드, 데이터베이스 연결 풀링, 배치 등등 문자 메시지를 보낼 수 있습니다.
4, 멀티 스레드 방식으로는 만들 수 있습니다
첫째, Thread 클래스 상속 실행 메소드를 오버라이드 (override)
class CreateThread extends Thread {
// run方法中编写 多线程需要执行的代码
publicvoid run() {
for (inti = 0; i< 10; i++) {
System.out.println("i:" + i);
}
}
}
publicclass ThreadDemo {
publicstaticvoid main(String[] args) {
System.out.println("-----多线程创建开始-----");
// 1.创建一个线程
CreateThread createThread = new CreateThread();
// 2.开始执行线程 注意 开启线程不是调用run方法,而是start方法
System.out.println("-----多线程创建启动-----");
createThread.start();
System.out.println("-----多线程创建结束-----");
}
}
start 메소드가 호출 된 후에, 코드는 위에서 아래로 실행하지 않았지만, 새로운 행정부가
- 참고 : 페인트 데모는 다른 실행 경로를 멀티 스레딩.
둘째,의 Runnable 인터페이스를 달성 run 메소드를 오버라이드 (override)
class CreateRunnable implements Runnable {
@Override
publicvoid run() {
for (inti = 0; i< 10; i++) {
System.out.println("i:" + i);
}
}
}
publicclass ThreadDemo2 {
publicstaticvoid main(String[] args) {
System.out.println("-----多线程创建开始-----");
// 1.创建一个线程
CreateRunnable createThread = new CreateRunnable();
// 2.开始执行线程 注意 开启线程不是调用run方法,而是start方法
System.out.println("-----多线程创建启动-----");
Thread thread = new Thread(createThread);
thread.start();
System.out.println("-----多线程创建结束-----");
}
}
익명의 내부 클래스 방식의 셋째, 사용
System.out.println("-----多线程创建开始-----");
Thread thread = new Thread(new Runnable() {
public void run() {
for (int i = 0; i< 10; i++) {
System.out.println("i:" + i);
}
}
});
thread.start();
System.out.println("-----多线程创建结束-----");
5, 상속 스레드 클래스 또는 좋은 구현의 Runnable 인터페이스를 사용하고 계십니까?
-
즉, 좋은 이유 상속을 계속 할 수있는 인터페이스를 구현을 달성하기 위해의 Runnable 인터페이스를 구현하는 클래스는 상속 될 수 없습니다.
6, 방법은 아직 실행하여 스레드 시작 방법이라고 시작?
- 열기 스레드 대신 실행 방법에주의를 호출하는 실행 스레드를 시작하지만 방법은 실행 방법은 인스턴스 지식을 호출 호출을 시작합니다.
(7) 상기 개체의 이름 쓰레드를 얻기
일반적인 스레드 API 메소드 | |
---|---|
스타트() | 스레드를 시작합니다 |
currentThread () | 현재 스레드 객체를 가져옵니다 |
getID () | 이 숫자는 0에서 시작하여 현재 스레드 ID 스레드 - 번호를 |
getName () | 현재 스레드의 이름을 가져옵니다 |
수면 (긴 공장) | 잠자는 스레드 |
중지() | 스레드를 중지 |
일반적인 스레드 생성자 | |
실() | 새로운 Thread 객체를 할당 |
스레드 (문자열 이름) | 이름으로 지정된 이름을 가진 새로운 Thread 객체를 할당합니다. |
스레드 (Runable R) | 새로운 Thread 객체를 할당 |
스레드 (Runable R, 문자열 이름) | 새로운 Thread 객체를 할당 |
8, 데몬 스레드
- 자바는 두 개의 스레드가, 하나는 다른 스레드의 보호자, 사용자 스레드입니다.
- 사용자 스레드는 메인 스레드가 사용자 스레드를 중지하지 않습니다 중지하기 위해 만든 사용자 정의 스레드를 의미
- 프로세스가 존재하거나 주 스레드를 중지하지 않습니다 데몬 스레드는 스레드 데몬이 중지됩니다.
- 데몬 스레드를 설정하는 setDaemon를 (사실) 메소드를 사용하여
public class DaemonThread {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("我是子线程...");
}
}
});
thread.setDaemon(true);
thread.start();
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
System.out.println("我是主线程");
}
System.out.println("主线程执行完毕!");
}
}
9, 멀티 스레드 작동 상태
- : 창조에서 스레드는 항상 다음과 같은 다섯 개 가지 상태 중 하나에 끝까지 실행하는 새로운 상태 , 준비 상태 , 실행 상태 , 상태 블로킹 과 죽음의 상태를
새로운 상태
- 当用new操作符创建一个线程时, 例如new Thread(r),线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码
就绪状态
- 一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回后,线程就处于就绪状态。
- 处于就绪状态的线程并不一定立即运行run()方法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运行线程。因为在单CPU的计算机系统中,不可能同时运行多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。对多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread scheduler)来调度的。
运行状态
当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法.
阻塞状态线程运行过程中,可能由于各种原因进入阻塞状态:1>线程通过调用sleep方法进入睡眠状态; 2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
3>线程试图得到一个锁,而该锁正被其他线程持有;
4>线程在等待某个触发条件;
死亡状态
- 有两个原因会导致线程死亡:
- - 1) run方法正常退出而自然死亡,
- - 2) 一个未捕获的异常终止了run方法而使线程猝死。
- 为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,则返回false.
join()方法作用
- 当在主线程当中执行到t1.join()方法时,就认为主线程应该把执行权让给t1
创建一个线程,子线程执行完毕后,主线程才能执行。
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(10);
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName() + "i:" + i);
}
}
});
t1.start();
// 当在主线程当中执行到t1.join()方法时,就认为主线程应该把执行权让给t1
t1.join();
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(10);
} catch (Exception e) {
}
System.out.println("main" + "i:" + i);
}
- 优先级
- 现代操作系统基本采用时分的形式调度运行的线程,线程分配得到的时间片的多少决定了线程使用处理器资源的多少,也对应了线程优先级这个概念。在JAVA线程中,通过一个int priority来控制优先级,范围为1-10,其中10最高,默认值为5。下面是源码(基于1.8)中关于priority的一些量和方法。
class PrioritytThread implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().toString() + "---i:" + i);
}
}
}
public class ThreadDemo4 {
public static void main(String[] args) {
PrioritytThread prioritytThread = new PrioritytThread();
Thread t1 = new Thread(prioritytThread);
Thread t2 = new Thread(prioritytThread);
t1.start();
// 注意设置了优先级, 不代表每次都一定会被执行。 只是CPU调度会有限分配
t1.setPriority(10);
t2.start();
}
}
Yield方法
Thread.yield()方法的作用:暂停当前正在执行的线程,并执行其他线程。(可能没有效果)
yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。
结论:大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。
总结
- 1.进程与线程的区别?
-
- 答:进程是所有线程的集合,每一个线程是进程中的一条执行路径,线程只是一条执行路径。
- 2.为什么要用多线程?
-
- 答:提高程序效率
- 3.多线程创建方式?
-
- 答:继承Thread或Runnable 接口。
-
- 4.是继承Thread类好还是实现Runnable接口好?
-
- 答:Runnable接口好,因为实现了接口还可以继续继承。继承Thread类不能再继承。
- 5.你在哪里用到了多线程?
-
- 答:主要能体现到多线程提高程序效率。
-
- 举例:分批发送短信、迅雷多线程下载等。
总结不易,给个关注吧 https://github.com/yunlongn