Rumah  >  Artikel  >  Java  >  Bagaimana untuk memahami benang dalam java

Bagaimana untuk memahami benang dalam java

王林
王林ke hadapan
2023-04-29 22:01:051128semak imbas

Bagaimana untuk memahami benang dalam java

Benang ialah laluan pelaksanaan dalam program adalah satu laluan pelaksanaan tunggal; kerana terdapat satu utas, terdapat juga berbilang benang kelebihan multi-threading adalah untuk meningkatkan penggunaan CPU. Dalam program berbilang benang, apabila satu utas mesti menunggu, CPU boleh menjalankan utas lain dan bukannya menunggu, meningkatkan kecekapan program.

Penciptaan berbilang benang

Kaedah 1: Mewarisi kelas Thread

Proses penciptaan Kaedah 1:

  • Tentukan subkelas MyThread Warisi kelas thread java.lang.Thread dan ganti kaedah run();

  • Buat objek kelas MyThread; Panggil objek utas Kaedah mula() memulakan utas (kaedah run() masih dilaksanakan selepas permulaan

    public class ThreadDemo01 {
        public static void main(String[] args) {
            MyThread myThread1 = new MyThread();
            myThread1.start();
            for (int i = 0; i < 3; i++) {
                System.out.println("主线程正在执行~~");
            }
        }
    }
    class MyThread extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                System.out.println("子线程正在执行~~");
            }
    
        }
    }
    //输出结果(不唯一):
    //主线程正在执行~~
    //主线程正在执行~~
    //主线程正在执行~~
    //子线程正在执行~~
    //子线程正在执行~~
    //子线程正在执行~~
  • Terdapat dua utas yang dilaksanakan dalam kod di atas, iaitu; utas utama dan utas kaedah utama Benang kanak-kanak dimulakan dengan memanggil start() pada mythread objek. Tetapi mengapa hasil output tidak unik? Sebabnya ialah preemption CPU akan berlaku di antara dua utas semasa pelaksanaan, dan sesiapa yang merampasnya dahulu akan melaksanakannya dahulu.

  • Jadi mengapa kita tidak terus menggunakan objek benang untuk memanggil kaedah run()? Jika run() dipanggil terus, ia hanyalah kaedah panggilan biasa, iaitu, satu utas, manakala kaedah start() digunakan untuk memulakan utas anak, supaya berbilang benang boleh berlaku.

  • Kelebihan dan kekurangan kaedah satu:

Kelebihan: Pengekodan mudah; dan tidak boleh diwarisi. Kelas lain tidak kondusif untuk pengembangan; . Tentukan kelas tugasan MyRunnable Laksanakan antara muka Runnable dan tulis semula kaedah run()

    2 Cipta objek MyRunnable;
  • 4. Panggil utas Kaedah mula() objek memulakan utas

  • public class ThreadDemo02 {
        public static void main(String[] args) {
            MyRunnable target = new MyRunnable();
            Thread thread = new Thread(target);
            thread.start();
            for (int i = 0; i < 3; i++) {
                System.out.println("主线程正在执行~~");
            }
        }
    }
    class MyRunnable implements Runnable{
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                System.out.println("子线程正在执行~~");
            }
    
        }
    }
    //输出结果(不唯一):
    //主线程正在执行~~
    //子线程正在执行~~
    //子线程正在执行~~
    //子线程正在执行~~
    //主线程正在执行~~
    //主线程正在执行~~
  • Perbezaan antara kod ini dan kaedah pertama ialah objek tugasan MyRunnable; dikapsulkan dalam Benang Tempat-tempat lain pada dasarnya tidak berubah.

    Kelebihan dan kekurangan kaedah kedua:
Kelebihan: Kelas tugasan benang hanya melaksanakan antara muka, dan boleh terus mewarisi kelas dan melaksanakan antara muka, yang sangat berskala

Kelemahan: Satu lagi lapisan pembungkusan objek pengaturcaraan, jika benang mempunyai hasil pelaksanaan, ia tidak boleh dikembalikan terus.

Seterusnya, kami juga menggunakan antara muka Runnable (bentuk kelas dalam tanpa nama) untuk mencapai penciptaan berbilang benang:

1 Cipta objek kelas dalam tanpa nama Runnable

2 . Serahkan pada Thread untuk diproses;

3 Panggil mula() objek thread untuk memulakan thread; utas yang perlu dibuat objek, manakala satu lagi berbilang benang melalui kelas dalaman tanpa nama. Dan blok kod ini juga boleh diperkemas melalui ungkapan lambda Saya tertanya-tanya adakah anda masih kagum dengan titik pengetahuan ini? Jika anda terlupa, anda boleh membaca artikel ini: Cara memahami ungkapan lambda dalam Java - Dipermudahkan

Kaedah tiga: Laksanakan antara muka Boleh Panggil
Thread构造器 方法
public Thread (String name) 可以为当前线程指定名称
public Thread (Runnable target) 封装Runnable对象成为线程对象
public Thread (Runnable target ,String name) 封装Runnable对象成为线程对象,并指定线程名称

Selepas mempelajari dua cara sebelumnya untuk mencipta berbilang benang Dalam masa hadapan, kita akan mendapati bahawa terdapat masalah: 1. Kaedah run() yang ditulis semula tidak boleh mengembalikan hasil secara langsung 2. Ia tidak sesuai untuk senario perniagaan yang perlu mengembalikan hasil pelaksanaan thread. Oleh itu, kita memerlukan cara ketiga untuk menyelesaikan masalah ini.

Proses penciptaan kaedah tiga:

1 Tentukan kelas untuk melaksanakan antara muka Boleh Panggil, mengatasi kaedah panggilan() dan merangkumkan perkara yang perlu dilakukan

2. Gunakan FutureTask untuk melaksanakan antara muka Boleh Dipanggil Objek dirangkumkan ke dalam objek tugasan benang

3. kaedah Thread untuk memulakan thread dan melaksanakan tugasan;

5 Selepas pelaksanaan thread selesai, dapatkan hasil pelaksanaan tugas melalui kaedah get() FutureTask.

public class ThreadDemo03 {
    public static void main(String[] args) throws Exception {
        MyCallable myCallable = new MyCallable();
        FutureTask<String> futureTask = new FutureTask<>(myCallable);
        Thread thread = new Thread(futureTask);
        thread.start();
        int sum= 0;
        for (int i = 0; i < 3; i++) {
            sum+=i;
        }
        System.out.println(sum);
        String s =futureTask.get();
        System.out.println(s);
    }
}
class MyCallable implements Callable<String > {
    @Override
    public String call(){
        int sum=0;
        for (int i = 0; i < 3; i++) {
            sum+=i;
        }
        return "子线程计算结果:"+sum;
    }
}
//输出结果:
//3
//子线程计算结果:3

方式三优缺点:

优点:

线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强;

可以在线程执行完毕后去获取 线程执行的结果;

缺点:

编码复杂一点;

总结

方式 优点 缺点
继承Thread类 编程比较简单,可以直接使用Thread类中的方法 扩展性较差,不能再继承其他的类,不能返回线程执行的结果
实现Runnable接口 扩展性强,实现该接口的同时还可以继承其他的类 编程相对复杂,不能返回线程执行的结果
实现Callable接口 扩展性强,实现该接口的同时还可以继承其他的类,可以得到线程的执行结果 编程相对复杂

常用方法

Thread获取和设置线程名称

方法名称 说明
String getName() 获取当前线程的名称,默认线程名称是Thread-索引
void setName(String name)

将此线程更改为指定的名称,通过构造器也可以设置线程名称

简单地通过一段代码让大家能够清晰地了解这个代码该如何使用:

public class ThreadDemo04 {
    public static void main(String[] args) throws Exception {
        thread thread1 = new thread();
        thread1.setName("1号子线程");
        thread1.start();
        thread thread2 = new thread();
        thread2.setName("2号子线程");
        thread2.start();
    }
}
class thread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(this.getName()+"正在执行任务"+i);
        }
    }
}
//输出结果:
//2号子线程正在执行任务0
//1号子线程正在执行任务0
//2号子线程正在执行任务1
//1号子线程正在执行任务1
//2号子线程正在执行任务2
//1号子线程正在执行任务2

Thread类的线程休眠方法

方法名称 说明
public static void sleep(long time) 让当前线程休眠指定的时间后再继续执行,单位为毫秒
public class ThreadDemo05 {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 5; i++) {
            System.out.println(i);
            if (i==3){
                Thread.sleep(5000);
            }
        }
    }
}
//输出结果:
//1
//2
//3
//在输出过3以后,等待5秒之后再进行输出
//4

Atas ialah kandungan terperinci Bagaimana untuk memahami benang dalam java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam