> Java > java지도 시간 > 본문

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

WBOY
풀어 주다: 2023-05-14 09:07:16
앞으로
1627명이 탐색했습니다.

멀티 스레드 프로그래밍은 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();
    }
}
로그인 후 복사

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

스레드가 동시에 실행됩니다.

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();
            }
        }
    }
}
로그인 후 복사

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

블로킹 상태에 진입한 후 다음 초 무엇 그 스레드를 깨우는 것에 대해?

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();
    }
}
로그인 후 복사

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?방법 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();//并行执行
    }
}
로그인 후 복사

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?직렬 시간이 병렬 시간보다 훨씬 길다는 것을 분명히 알 수 있습니다.

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?Thread 클래스의 기타 속성 및 메서드

Thread의 일반적인 생성자

속성 ID이름 StatusPriority백그라운드 스레드가스레드가 살아 있는지 스레드 중단 여부
  • ID是线程唯一的标识,不同的线程之间不会重复

  • 名称是各种调试工具用到的

  • 状态标识当前线程的一种情况

  • 优先级高的线程,理论上更容易被执行到

  • 是否存活简单理解为run()方法是否执行结束

给一个线程起名字

Thread(String name) 这个东西是给thread对象起一个名字,具体起什么名字和线程的执行效率无关,起名字主要依靠于程序员,方便程序员在后期进行调试。

public class TestDemo17 {
    public static void main(String[] args) {
        //给线程器名字
        Thread t1 = new Thread(()->{
            while(true) {
                System.out.println("hello thread1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"thread1");

        Thread t2 = new Thread(()->{
            while(true) {
                System.out.println("hello thread2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"thread2");
        t1.start();
        t2.start();
    }
}
로그인 후 복사

那么怎样才能看到,我们定义好的线程名字呢?

注意:当我们要查看线程名字的时候,程序必须要正在执行,否则我们查找不到对应的线程名字。

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

判断一个线程是否存活

简单的说就是操作系统中我们创建出来的线程是否还存在

Thread t 的生命周期和操作系统中对应的线程的生命周期并不是完全一致的。

我们在定义一个线程类后,在调用t.start()方法之前,操作系统中是没有我们创建出来的线程的。在线程类中的run()方法执行完之后,我们在操作系统中创建出来的线程就被销毁了!但是线程t对象还存在。

  • 总而言之,在调用t.start()方法之前,在执行run()方法之后,此时操作系统中是没有我们创建出来的线程的

  • 在调用t.start()方法之后,在指向run()方法之前,此时操作系统中存在我们创建出来的线程 判断该线程是由是后台线程

如果一个线程是后台线程,那么这个线程就不会进行进程退出

如果一个线程是前台线程,那么这个这个线程就会影响到进程的退出。我们以上的代码在创建线程,那些线程都是前台线程,假如现在有前台线程t1,t2, 现在即使main线程执行结束,但是此时还不可以退出线程,必须要将t1,t2线程执行结束之后,整个线程才会结束。

假如现在有两个线程t1,t2,它们都是后台线程,那么如果现在main线程执行结束,整个进程就执行结束,此时我们会强制停止t1,t2线程。

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
로그인 후 복사

Thread的其他常见属性

创建线程

创建线程:定义出一个线程类,然后启动线程t.start(),其中start()方法决定系统是不是真的创建出线程。

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

线程的中断

中断线程简单的可以理解成为就是让该线程中的run()方法执行结束。还有一个特殊的就是main线程,如果想要中断main线程,那么就需要把main线程执行完。

中断线程方法一:设置一个标志位

public class TestDemo21 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
           while(!Thread.currentThread().isInterrupted()) {
               System.out.println("hello thread");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        //启动t线程
        t.start();
        //在main线程中中断t线程
        //5s之后中断t线程
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.interrupt();
    }
}
로그인 후 복사
로그인 후 복사

运行结果:当t线程中的sout语句被执行5次之后,线程停止。

上面的这种写法不够严谨,只适用于该场合,如果化作是别的代码场合的话,有可能不会终止线程。

这里用一种较好的方法,使用Thread类中自带的检查线程是否断开。

Thread.interrputed() 这是一个静态方法 Thread.currentThread().isinterrupted() 其中Thread.cerrentThread()可以获得线程的引用。

t.interrupted()用于中断线程

public class TestDemo21 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
           while(!Thread.currentThread().isInterrupted()) {
               System.out.println("hello thread");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        //启动t线程
        t.start();
        //在main线程中中断t线程
        //5s之后中断t线程
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.interrupt();
    }
}
로그인 후 복사
로그인 후 복사

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

在我们上边中断线程,判断标志位的时候,我们使用的是第三种方法。设置标志位的时候使用的是第一种方法。

在我们的日常开发中,经常会用到Thread.currentThread().isInterrupted()来判断标志位,判断该线程是否被中断。

还有一种方法判断标志位,但是它是一个静态方法,只能判断一个类中只有一个线程的情况下,这个方法就是Thread.isinterrupted()方法

Thread.currentThread().isinterrupted()这个方法判断的是Thread的普通成员,每个实例都有一个标志位。

在我们以后就无脑使用Thread.currentThread().isInterrupted()方法,判断线程是否中断(标志位)

线程的等待

在前面我们也介绍到join()方法,这个方法就是让线程与线程之间,有了一定的执行顺序。我们知道在多线程中的调度是随机的,不确定的,多线程的执行靠调度器安排,该调度器的安排是随机的,不规律的。其实线程等待就是一个行之有效的方法,实际上就是控制线程执行的先后顺序。

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"); }}
로그인 후 복사

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

获取线程的引用

使用方法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();
    }
}
로그인 후 복사

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

线程的休眠

其实线程休眠就是调用Thread.sleep()方法。

回顾之前的学习内容,我们知道我们使用PCB描述一个进程,使用双向链表来组织进程。这种说法是针对一个进程中只有一个线程的情况下。

那么如果一个进程中有多个线程存在,那么每个线程就有一个PCB,那么每个进程都会有一组PCB,

PCB上有一个字段为tgroupId,这个id就相当于是进程的id,进程中的每个线程的tgroupId都是相同的。

那么进程控制块(process contral block)和线程有什么关系呢?

其实在linux中是不区分进程和线程的,所谓的线程是程序员自己搞出来的,实际上linux只认进程控制块(PCB),实际上线程就相当于一个轻量级进程。

Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?

위 내용은 Java에서 Thread 클래스를 사용하는 방법과 해당 속성은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
메서드 가져오기
getId()
getName()
getState()
getPriority()
Daemon()
isAlive()
중단됨()