JAVA多线程

一、相对于多进程,多线程的优势如下:

1、 进程之间不能共享数据,线程可以
2、系统需要为新创建的进程重新分配系统资源,而创建线程代价较小。
3、java内置多线程功能,简化编程。

二、线程的创建和启动有三种方式:

2.1、继承Thread类创建线程类

1、定义一个继承Thread类的子类,重写run()方法
2、创建Thread子类的实例。
3、调用start()方法启动线程

 public class FirstThread extends Thread{

    @Override //重写Thread的run方法
    public void run(){
        System.out.println("继承Thread");
     }
 }


 public class Test {
 
    public static void main(String[] args) {
        FirstThread firstThread = new FirstThread();//线程对象
        firstThread.start();
     }
 }

2.2、实现Runnable接口创建线程类
1、定义Runnable接口的实现类,重写接口的run()方法
2、创建Runnable实现类的实例,以此作为Thread的target对象,所以Thread对象才是真正的线程对象。
3、调用start()方法启动线程

 public class FirstRunnable implements Runnable{

    @Override //重写Thread的run方法
    public void run(){
        System.out.println("实现 Runnable 接口");
     }
 }

 public class Test {
    public static void main(String[] args) {
        FirstRunnable firstRunnable = new FirstRunnable();//firstRunnable作为Thread的target对象
        Thread firsrThread =new Thread(firstRunnable);
        firsrThread.start();
    }
 }

2.3、通过Callable和Future创建线程
1、创建Callable接口的实现类,并实现call()方法(作为线程的执行体,有返回值)。
2、创建Callable实现类的实例,并使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
3、将FutureTask对象作为Thread对象的target,创建该Thread对象并启动新线程。
4、调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。

 public class FirstCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("first Callable");
        return "first Callable";
      }
  }

 public class Test {
    public static void main(String[] args) {

    Callable<String> callable = new FirstCallable();//创建Callable 实例
    FutureTask<String> task = new FutureTask<>(callable);//FutureTask包装Callable 对象
    Thread thread = new Thread(task);

     try {
         thread.start();
         System.out.println("return: "+ task.get());
     } catch (InterruptedException e) {
        e.printStackTrace();
     } catch (ExecutionException e) {
        e.printStackTrace();
     }
   }
 }

三、线程三种创建方式的比较

3.1、使用继承Thread类的方式创建多线程时:

优势
编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。
劣势:
线程类已经继承了Thread类,所以不能再继承其他父类。

3.2、采用RUnnable和Callable接口的方式创建多线程时:

优势:
线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
劣势:
编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

3.3、Runnable和Callable的区别:

1、Callable规定(重写)的方法是call(),Runnable规定(重写)的方法是run()。
2、Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
3、Call方法可以抛出异常,run方法不可以。
4、运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

四、示例

4.1、extends Thread

public class Start1 {
    public static void main(String[] args) {

    StartThread1 wugui = new StartThread1();
    StartThread1 tuzi =new StartThread1();

   //设置线程优先级
    wugui.setPriority(1);
    tuzi.setPriority(10);

   //设置线程名称
    wugui.setName("乌龟线程");
    tuzi.setName("兔子线程");

  //启动线程
   wugui.start();
   tuzi.start();
}


public class StartThread1 extends Thread{

    public  void run(){
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName());//打印线程调用的名称
        System.out.println(thread.getPriority());//优先级
        for(int i=0;i<100;i++){
            System.out.println(getName()+"跑到了第"+i+"米");
            if ( i==98&&thread.getName().equals("兔子线程")){
                System.out.println("兔子睡着了");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4.2、implements Runnable

 public class Test {
    public static void main(String[] args) {
        FirstRunnable firstRunnable = new FirstRunnable();

        Thread tuzi = new Thread(firstRunnable);//将任务对象放入线程对象中
        Thread wugui =new Thread(firstRunnable);

        tuzi.setName("小兔子线程");   //改变线程名称
        wugui.setName("小乌龟线程");

        tuzi.setPriority(9);//线程优先级
        wugui.setPriority(1);//线程优先级

        tuzi.start();
        wugui.start();
     }
 }

 public class FirstRunnable implements Runnable{
     @Override //重写Thread的run方法
     public void run(){
         Thread thread = Thread.currentThread();
         for ( int i=1;i<=100;i++) {
         
            System.out.println(thread.getName()+"跑到了第"+i+"米");
           try {
               if ( i==99&&thread.getName().equals("小兔子线程")){
                   System.out.println("小兔子睡着了----");
                   Thread.sleep(5000);
               }
           }catch (Exception e){
               e.printStackTrace();
            }
         }
     }
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值