멀티 스레드 프로그래밍은 Java에서 수행할 수 있습니다. 스레드 작업을 나타내기 위해 Java 표준 라이브러리에 Thread 클래스가 제공됩니다. Thread 클래스는 멀티스레드 프로그래밍을 해결하기 위해 Java 표준 라이브러리에서 제공하는 API 집합으로 간주할 수 있습니다. 생성된 Thread 인스턴스는 운영 체제의 스레드와 일대일 대응을 갖습니다. 운영 체제는 스레드에 대한 API(C 언어 스타일)를 제공하고 Java는 이를 Thread 클래스에 캡슐화합니다.
스레드 만들기
방법 1: Thread 클래스 상속
class MyThread extends Thread{
@Override
public void run() {
//此时只是定义处理一个线程类,在系统中总是还没有创建出 新的线程。
System.out.println("hello thread");
}
}
public class TestDemo11 {
public static void main(String[] args) {
//创建线程
Thread t = new MyThread();
//启动线程,在系统中创建出了新的线程
t.start();
}
}
로그인 후 복사
스레드가 동시에 실행됩니다.
class MyThread3 extends Thread{
@Override
public void run() { //定义一个线程类
while (true) {
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TestDemo13 {
public static void main(String[] args) {
Thread t = new MyThread3();
t.start();//启动t线程
while(true){
System.out.println("hello main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
로그인 후 복사
블로킹 상태에 진입한 후 다음 초 무엇 그 스레드를 깨우는 것에 대해?
1s当执行一个线程中的代码之后실행된 두 스레드에 인쇄된 로그의 순서가 불확실한 것을 볼 수 있습니다. 각 라운드에서 1초 이후에는 스레드 스레드를 깨울지 메인 스레드를 깨울지 여부가 불확실합니다. (선제 실행) 운영 체제의 경우 스레드가 예약되는 순서는 거시적으로 무작위입니다
여기서 Thread.sleep() 메서드를 설명하겠습니다. sleep() 메서드는 ms 수준에서 그다지 정확하지 않습니다. 이 메서드를 호출한 후 스레드는 강제로 중간 차단(수면 상태)이 되지만 차단 시간이 지나면 스레드는 Thread.sleep(1000)인 경우 1초 후에 즉시 컵에서 계속 실행되지 않습니다. 통과하면 차단 시간이 종료되지만 1001ms가 되면 스레드가 즉시 실행되지 않을 수 있습니다. 어쩌면 운영 체제의 컵이 다른 스레드로 인해 바쁜 것일 수도 있습니다. 어쩌면 스레드가 1006ms에서 실행될 수도 있습니다.
방법 2: Runnable 인터페이스에서 run() 메서드 구현
//Runnable其实就是描述一个任务
//创建一个类,实现Runnable接口,重写Runnable类中的run方法,在run()方法中,描述的是该线程要指向的哪些任务。
class MyThread2 implements Runnable{
@Override
public void run() {
System.out.println("hello thread");
}
}
public class TestDemo12 {
public static void main(String[] args) {
//创建线程,把创建好的Runnable实例传给Thread实例
Thread t = new Thread(new MyThread2());
t.start();
}
}
로그인 후 복사
방법 3: 내부 클래스 사용
방법 3은 실제로 위의 두 코드를 익명 내부 클래스로 변경하는 방법 1의 복제본입니다. .
public class TestDemo14 {
public static void main(String[] args) {
Thread t1 = new MyThread(){
@Override
public void run() {
System.out.println("hello thread1");
}
};
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello thread2");
}
});
t1.start();
t2.start();
}
}
로그인 후 복사
방법 4: Lambmd 표현식 사용
public class TestDemo15 {
public static void main(String[] args) {
//其实就是使用lambad表达式代替Runnable
Thread t1 = new Thread(()->{
//()表示无参的run()方法
System.out.println("hello thread1");
});
}
}
로그인 후 복사
스레드 사용의 이점
멀티스레딩의 이점을 보다 편리하게 반영하기 위해 여기서는 0부터 시작하여 10_0000_0000이 될 때까지 1씩 증가시킵니다. 직렬 메서드와 병렬 메서드를 사용하고 비교를 위해 코드 실행 시간을 가져옵니다.
public class TestDemo16 {
public static void func1() throws InterruptedException {
long big = System.currentTimeMillis();
//串行执行
Thread t = new Thread(()->{
long a = 0;
for(long i = 0;i<10_0000_0000;i++){
a++;
}
});
t.start();
t.join();
long end = System.currentTimeMillis();
System.out.println("串行消耗时间:" + (end - big) + "ms");
}
public static void func2() throws InterruptedException {
long big = System.currentTimeMillis();
Thread t1 = new Thread(()->{
long b = 0;
for(long i = 0;i< 10_0000_0000 / 2;i++){
b++;
}
});
t1.start();
Thread t2 = new Thread(()->{
long c = 0;
for(long i = 0;i<10_0000_0000/ 2;i++){
c++;
}
});
t2.start();
t1.join();
t2.join();
long end = System.currentTimeMillis();
System.out.println("并行执行消耗时间:" + (end - big) + "ms");
}
public static void main(String[] args) throws InterruptedException {
func1();//串行执行
func2();//并行执行
}
}
public class TestDemo18 {
public static void main(String[] args) {
Thread t = new Thread(()->{
System.out.println("hello thread");
});
t.start();
System.out.println(t.isDaemon());
}
}
//因为我们创建的是一个前台线程,所以返回false
public class TestDemo22 {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> public static void main(String[] args) throws InterruptedException {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> Thread t = new Thread(()->{<!--{C}%3C!%2D%2D%20%2D%2D%3E--> for(int i = 0;i<5;i++){<!--{C}%3C!%2D%2D%20%2D%2D%3E--> System.out.println("hello thread"); try {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> Thread.sleep(1000); } catch (InterruptedException e) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> e.printStackTrace(); } } }); t.start(); t.join();//main线程调用t.join()方法,main线程就处于阻塞状态,当t线程执行完后,唤醒main线程执行后序代码 System.out.println("hello main"); }}
로그인 후 복사
获取线程的引用
使用方法Thread.currentTread()就可以该线程的实例。
public class TestDemo23 {
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run() {
//获取当前线程的引用
//System.out.println(Thread.currentThread().getName());
//因为当前使用的匿名内部类是继承自Thread类,Thread就是该匿名内部类的父类,所以可以通过this得到当前Thread的实例
System.out.println(this.getName());
}
};
t.start();
}
}