java语言基础(88)——多线程(实现多线程的四种方式)

来源:互联网 发布:还有哪些社交软件 编辑:程序博客网 时间:2024/06/07 01:40

至于什么是线程,什么是进程,多线程的意义与多进程的意义,不是本文的终点,本文着重记录多线程的实现方式。

方式一:

将类声明为Thread的子类,该子类应该重写Thread类的run方法。run方法中的代码是被多线程执行的。

实现过程

1 声明Thread子类

2 重写run方法

3 创建子类对象

4 启动线程(调用start方法启动线程,然后由jvm自动调用run方法)

示例代码:

package ThreadDemo;public class MyThreadOne extends Thread {  public void run(){  for(int i=0;i<200;i++){  System.out.println(i);  }  }}
package ThreadDemo;public class ThreadDemo { public static void main(String[] args) {  MyThreadOne my1 = new MyThreadOne();//创建第一个线程  MyThreadOne my2 = new MyThreadOne();//创建第二个线程  my1.start();//启动线程  my2.start();//启动线程}}
运行上述代码后,如果我们看到数字并不是0-199 和 0-199顺序输出的,那么就证明两个线程存在争夺cup执行权的情况,说明我们实现了多线程的效果


设置和获取线程名称:
我们可以通过getName()方法获得线程的名称,并可以通过setName()方法或带参构造来设置线程的名称,以此来让我们区分不同的线程。

那么如何获取非Thread子类的线程名称呢,比如main方法的线程名称。我们可以用如下方法来获取。

Thread.currentThread().getName()


线程调度,获取和设置线程优先级:

线程调度的两种模型

1 分时调度模型,所有线程轮流使用cpu,平均分配每个线程占用cpu的时间片

2 抢占式调度模型,优先让优先级高的线程使用cpu,优先级相同则随机选取,优先级高的线程获取相对较多的cpu时间片。

通过java api文档我们可以知道,线程默认的优先级为5,最高为10,最低为1

getPriority 和 setPriority 分别可以获取和设置线程的优先级

如下:

package ThreadDemo;public class ThreadDemo { public static void main(String[] args) {  MyThreadOne my1 = new MyThreadOne();  MyThreadOne my2 = new MyThreadOne();  my1.setPriority(10);//  System.out.println(my1.getPriority());//  System.out.println(my2.getPriority());  my1.start();  my2.start();  }}
设置优先级后,多次运行,我们会发现优先级高的确实会优先执行。

方式二:

声明类实现runnable接口。

实现过程

1 声明自定义类,并且实现runnable接口

2 重写run方法

3 创建类的对象实例

4 创建Thread实例,把刚才的自定义类的实例作为参数传递

示例代码:

package ThreadDemo;public class MyThreadTwo implements Runnable{public void run() {for(int i=0;i<100;i++){System.out.println(Thread.currentThread().getName()+":"+ i);}}}
package ThreadDemo;public class ThreadDemo { public static void main(String[] args) {MyThreadTwo mtt = new MyThreadTwo();    Thread t1 = new Thread(mtt);    Thread t2 = new Thread(mtt);    t1.start();    t2.start();}}
此方式解决了java单继承的局限性,并且较好的体现了面向对象的思想。把线程代码抽取(分离)出来,更适合多个程序调用。

方式三:

实现callable接口,配合线程池实现多线程,并且此方式还支持泛型返回值。

示例代码:

package ThreadDemo;import java.util.concurrent.Callable;public class MyCallable implements Callable<Integer>{private int num;public MyCallable(int num){this.num = num;}  public Integer call(){  int sum = 0;  for(int x=0;x<=num;x++){  sum += x;  }  return sum;  }}

package ThreadDemo;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class ThreadPoolDemo { public static void main(String[] args) throws InterruptedException, ExecutionException { // 创建线程池ExecutorService es = Executors.newFixedThreadPool(2);// 执行Runnable 或 Callable 代表的线程Future<Integer> f1 = es.submit(new MyCallable(100));Future<Integer> f2 = es.submit(new MyCallable(200)); //得到返回值Integer i1 = f1.get();Integer i2 = f2.get();System.out.println(i1);System.out.println(i2);        es.shutdown();}}


方式四:

匿名内部类方式

new Thread(){public void run(){// ....}}.start();
匿名内部类还可以用 Runable方式来实现。




原创粉丝点击