以前は、誰もがシングルスレッドのプログラムを作成し、メソッドをすべて main 関数で呼び出していたのと同様に、その効率が特に低いことがわかります。 Python. Web サイトにアクセスすると、データ量が多すぎて血を吐きそうになります。今日は Java の同時プログラミングとマルチスレッドの学習について見ていきます
Thread の継承
Thread
を継承すると を直接呼び出せる理由> start()
メソッドはスレッドを開始します。start()
自体は Thread のメソッドであるため、つまり Thread の start() メソッドを継承しているため、このクラスのオブジェクトはstart() を呼び出すことができます スレッドを開始します//继承Threadpublic class MyThread extends Thread { public void run() {for (int i = 0; i < 10; i++) { System.out.println(this.getName()+"正在跑"); } } }public class Test{public static void main(String[] args) { Mythread t1=new MyThread(); //创建对象t1.start(); //启动线程} }Thread
可以直接调用start()
方法启动线程呢,因为start()
本身就是Thread的方法,也就是继承了Thread的start()方法,因此这个类的对象可以调用start()启动线程
//实现Runnable接口public class Demo implements Runnable { @Overridepublic void run() {for(int i=0;i<10;i++) { System.out.println(Thread.currentThread().getName()+"正在跑"); } } }//测试类public class Test{public static void main(String[] args) { Demo d=new Demo(); //创建对象Thread thread1=new Thread(d); //为对象创建一个线程Thread thread2=new Thread(d); //创建另外一个线程//同时启动两个线程thread1.start(); thread2.start(); } }
注意: 继承
Thread
类的创建方法一个对象只能创建一个线程,并不能多个线程共用一个对象,只能一个线程对应一个对象,因此我们来看看实现Runnable
接口的类来实现多个线程共享同一个对象
//普通的一个类public class Simple {public void display() {for(int i=0;i<10;i++) { System.out.println(Thread.currentThread().getName()+"正在跑"); } } }//线程测试类public class Test {public static void main(String[] args) { //如果在外面必须使用final,当然也可以直写在run方法中,不过写在外面可以实现多个线程共享一个对象//写在run方法中当前对象只能为一个线程使用,和继承Thread类一样的效果final Simple simple=new Simple(); //下面创建使用同一个对象创建同两个线程,实现多个线程共享一个对象,和实现Runnable接口一样的效果Thread t1=new Thread(){public void run() { simple.display(); }; }; Thread t2=new Thread(){public void run() { simple.display(); }; }; //启动这两个线程t1.start(); t2.start(); }}
从上面可以清楚的看到实现
Runnable
接口的类一个对象可以供多个线程共享,并不像继承Thread类只为一个线程使用
直接在
main
方法中创建,如果创建的普通类的对象在外面,那么必须是final修饰,可以实现多个线程同时共享一个对象,这个和实现Runnable
接口一样,这时候就要控制同步条件了,如果在run方法中定义对象,那么,就是一个线程对应一个对象,这个就和继承Thread类一样的效果。所以可以根据条件自由选择
//线程的类,继承Threadpublic class MyThread1 extends Thread {public void run() { // 重载run方法,并且在其中写线程执行的代码块for (int i = 0; i < 10; i++) {// 获取线程的id和nameSystem.out.println("Thread-Name: " + this.getName() + " Thread-id: " + this.getId());try {this.sleep(1000); // 线程休眠1秒} catch (InterruptedException e) { e.printStackTrace(); } } } }//线程测试的类public class Test {public static void main(String[] args) { MyThread1 t1 = new MyThread1(); // 创建线程t1.setName("第一个线程"); // 设置线程的名字MyThread1 t2 = new MyThread1(); t2.setName("第二个线程"); t1.start(); // 启动线程,开始运行t2.start(); } }
static void sleep(long mils)
使正在运行的线程休眠mils毫秒,但是这里需要注意的是如果线程加了锁,那么使线程休眠并不会释放锁
String getName()
得到线程的名称,上面的程序中已经使用了这个方法
void setName(String name)
设置正在运行的线程的名字为name
start()
启动线程,线程的创建并不意味着线程的启动,只有调用start()方法线程才是真正的开始运行
long getId()
返回线程的标识符
run()
线程执行的代码都放在run()方法中,在run方法中的调用是有序的,都是按照程序运行的顺序开始执行
下面使用上面的方法创建一个实例
//线程类public class MyThread1 extends Thread {public void run() { // 重载run方法,并且在其中写线程执行的代码块for (int i = 0; i < 10; i++) {// 获取线程的id和nameSystem.out.println("Thread-Name: " + this.getName() + " Thread-id: " + this.getId());try {this.sleep(1000); // 线程休眠1秒} catch (InterruptedException e) { e.printStackTrace(); } } } }//测试类public class Test {public static void main(String[] args) { MyThread1 t1 = new MyThread1(); // 创建线程t1.setName("第一个线程"); // 设置线程的名字t1.start(); // 启动线程,开始运行try { t1.join(); //阻塞其他线程,只有当这个线程运行完之后才开始运行其他的线程} catch (InterruptedException e) { e.printStackTrace(); }for (int i = 0; i < 10; i++) { System.out.println("主线程正在运行"); } } }//输出结果/*Thread-Name: 第一个线程 Thread-id: 9Thread-Name: 第一个线程 Thread-id: 9Thread-Name: 第一个线程 Thread-id: 9Thread-Name: 第一个线程 Thread-id: 9Thread-Name: 第一个线程 Thread-id: 9Thread-Name: 第一个线程 Thread-id: 9Thread-Name: 第一个线程 Thread-id: 9Thread-Name: 第一个线程 Thread-id: 9Thread-Name: 第一个线程 Thread-id: 9Thread-Name: 第一个线程 Thread-id: 9主线程正在运行主线程正在运行主线程正在运行主线程正在运行主线程正在运行主线程正在运行主线程正在运行主线程正在运行主线程正在运行主线程正在运行 */
void join()
等待该线程终止才能运行其他的线程
void join(long mils)
等待该线程的时间为mils毫秒,一旦过了这个时间其他线程正常执行
//线程类public class MyThread1 extends Thread {public void run() { // 重载run方法,并且在其中写线程执行的代码块for (int i = 0; i < 10; i++) {// 获取线程的id和nameSystem.out.println("Thread-Name: " + this.getName() + " Thread-id: " + this.getId());try {this.sleep(1000); // 线程休眠1秒} catch (InterruptedException e) { e.printStackTrace(); } } } }//测试类public class Test {public static void main(String[] args) { MyThread1 t1 = new MyThread1(); // 创建线程t1.setName("第一个线程"); // 设置线程的名字MyThread1 t2 = new MyThread1(); t2.setName("第二个线程"); t2.setPriority(8); //设置第二个线程的优先级为8,第一个线程的优先级为5(是默认的)t1.start(); t2.start(); } }/* * 从上面的运行结果可以看出大部分的第二个线程都是在第一个线程之前开始执行的,也就是说优先级越高获得cpu执行的几率就越大 * /
getPriority()
得到当前线程优先级
setPriority(int num)
更改线程的优先级(0-10)默认的是5,优先级越高获得cpu资源的几率就会越高
//测试类public class MyThread1 extends Thread {public void run() { // 重载run方法,并且在其中写线程执行的代码块for (int i = 0; i < 10; i++) {// 获取线程的id和nameSystem.out.println("Thread-Name: " + this.getName() + " Thread-id: " + this.getId());try { Thread.sleep(1000); //休眠一秒,方便主线程运行结束} catch (InterruptedException e) { e.printStackTrace(); } } } }public class Test {public static void main(String[] args) { MyThread1 t1 = new MyThread1(); // 创建线程t1.setName("第一个线程"); // 设置线程的名字t1.setDaemon(true); t1.start();for (int i = 0; i < 1; i++) { System.out.println(i); } } }//结果:/* 0123456789Thread-Name: 第一个线程 Thread-id: 9*//* * 从上面的结果可以看出,一旦主线程结束,那么守护线程就会自动的结束 *
setDaemon(boolean)
是否设置为守护线程,如果设置为守护线程,那么主线程销毁守护线程也会随之销毁- 注:
isDaemon()
Thread
クラスの作成メソッドを継承します。オブジェクトは 1 つのスレッドと複数のスレッドのみを作成できます。 1 つのオブジェクトを共有することはできません。1 つのスレッドが 1 つのオブジェクトに対応するため、複数のスレッドが同じオブジェクトを共有できるようにするRunnable
インターフェースを実装するクラスを見てみましょう
上記から明らかなように、Runnable
インターフェイスを実装するクラスのオブジェクトは、1 つのスレッドでのみ使用される Thread クラスの継承とは異なり、複数のスレッドで共有できます
main
メソッド内で直接作成します。作成した通常のクラス オブジェクトが外部にある場合は、複数のスレッドで同時にオブジェクトを共有する必要があります。このとき、同期条件を制御するために、runメソッド内でオブジェクトを定義すると、1つのスレッドが1つのオブジェクトに対応し、Threadクラスを継承するのと同じ効果になります。条件に応じて自由に選択できます🎜🎜🎜rrreee🎜🎜よく使われる方法🎜🎜static void sleep(long mils)
スレッドはミリ秒間スリープしますが、ここで注意する必要があるのは、スレッドがロックされている場合、スリープしてもロックは解放されないということです🎜🎜🎜🎜🎜String getName()
このメソッドは上記のプログラムで使用されています🎜🎜🎜🎜🎜void setName( String name)
実行中のスレッドの名前を name に設定します🎜🎜🎜🎜🎜start ()
スレッドを開始します。スレッドの作成は、start() メソッドが呼び出された場合にのみ、スレッドの開始を意味します。🎜🎜🎜🎜🎜long getId ()
スレッドの識別子を返します 🎜🎜🎜🎜🎜run()
スレッドによって実行されるコードは run() メソッドに配置され、run メソッド内の呼び出しは順番に行われ、すべてプログラムの実行順序で実行されます。インスタンスを作成するメソッド: class=" list-paddingleft-2">void join()
他のスレッドを実行する前にスレッドが終了するのを待ちます🎜🎜 void join(long mils)
このスレッドの待機時間は mils ミリ秒です。この時間が経過すると、他のスレッドは 🎜🎜rrreee🎜🎜getPriority()
現在のスレッドの優先度を取得します🎜🎜setPriority(int num)
スレッドの優先度を変更します (0- 10) デフォルトは 5 で、優先度が高くなります。CPU リソースを取得する可能性が高くなります🎜🎜🎜🎜🎜Use🎜🎜rrreee🎜🎜setDaemon (boolean)
デーモン スレッドに設定されていますか。デーモン スレッドとして設定されている場合、デーモン スレッドが破棄されるとメイン スレッドも破棄されます🎜🎜isDaemon() code> デーモンスレッドかどうかを判断するには🎜🎜🎜🎜🎜use🎜🎜rrreee 🎜🎜🎜🎜
以上がThreadの定義と共通メソッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。