zoukankan      html  css  js  c++  java
  • 实现多线程

    1.在Java中,如果要实现多线程,那么就必须依靠一个线层的主体类,但是这个主体类在定义的时候也需要一些特殊的要求,这个类可以继承Thread类,实现Runable接口或实现Callable接口来完成定义。

    1.1 Thread类实现多线程

    MyThread.java

     class MyThread extends Thread {
        private String title;
        public MyThread(String title) {
        	this.title=title;
        }
    	//任何继承了Thread类的线程主体类就是一个线程的主类,同时线程类中需要明确复写父类的run()方法
    	@Override
    	public void run() {
    		//线程逻辑代码
    		for(int i=0;i<10;i++) {
    			System.out.println(this.title+"运行"+i+"次");
    		}
    	}
    }
    

    test.Java

    public class Test {
       public static void main(String[] args) {
    	new MyThread("线程A").start();
    	new MyThread("线程B").start();;
    	new MyThread("线程C").start();
    }
    }

     多线程之间彼此交替执行,但是每次的执行结果肯定是不一样的。要先启动线程就必须依靠Thread类的start()方法,线程启动之后会默认调用run()方法。

    面试题1:为什么线程启动的时候必须调用start()方法而不是直接调用run()方法呢? 

    Thread类源码:

     public synchronized void start() {
         
            if (threadStatus != 0)
                throw new IllegalThreadStateException();
            group.add(this);
            boolean started = false;
            try {
                start0();//private native void start0();
                started = true;
            } finally {
                try {
                    if (!started) {
                        group.threadStartFailed(this);
                    }
                } catch (Throwable ignore) {
               
                }
            }
        } 


        调用start()方法后会继承调用start0()方法,调用被Native关键字修饰的start0()方法,而native关键字会是指Java本地接口调用,即使用本地系统的函数功能完成,多线程的实现需要操作系统的支持,start0()方法没有方法体

    而把这个方法体直接交给Jvm去实现,Jvm通过调度算法调用本地系统的函数功能完成。而直接调用run()方法只是普通的方法调用并不能实现多线程。
    2.Runable接口实现多线程
    面向对象的程序设计通过实现标准定义与解耦操作,所以多线程又提供了Runable接口实现多线程开发。
    Runable.java
    @FunctionalInterface
    public interface Runnable {
    public abstract void run();
    }

     一旦实现Runable接口则MyThread类中就不再有start()方法,这时候要启动线程需要利用Thread的构造方法,向其中传入Runable的实现对象

    public class MyRunnable implements Runnable{
    
    	private String ThreadName;
    	public MyRunnable(String ThreadName) {
    	  this.ThreadName=ThreadName;	
    	}
    	@Override
    	public void run() {
    		for(int i=0;i<10;i++) {
    			System.out.println(this.ThreadName+"运行"+i+"次");
    		}	
    	}
    
    }
    public class Test {
       public static void main(String[] args) {
    	   
          Thread threadA=new Thread(new MyRunnable("A"));
          Thread threadB=new Thread(new MyRunnable("B"));
          Thread threadC=new Thread(new MyRunnable("C"));
          threadA.start();
          threadB.start();
          threadC.start();
    }
    }
    

     2.1Thread类与Runnable实现多线程的区别’

      Thread.java

    public  class Thread implements Runnable {  //内容}
    

    Runnable.java

    @FunctionalInterface
    public interface Runnable {
        public abstract void run();
    }
    

     Thread类是Runnable的实现类,Runable是一个父类接口,所以之间继承Thread类实际上还是复写了Runnable接口的Run()方法,两者都可以实现完全相同的效果,如果直接继承Thread类,那么资源本身就是一个线程对象了。

    3.Callable接口实现多线程

    Java针对多线程执行完毕后不返回信息的缺陷,提供了Callable接口。

    public class MyCallable implements Callable<String>{
        //定义时设置一个泛型,此泛型的类型就是返回数据的类型
    	@Override
    	public String call() throws Exception {
    		for(int i=0;i<10;i++) {
    			System.out.println("线程执行!");
    		}	
    		return "结果";
    	}
    
    }

     3.1 callable接口与FutureTask类的关系

      

    FutureTask<String> task=new FutureTask<>(new MyCallable());
    new Thread(task).start();
    System.out.println("线程返回的结果"+task.get());
    

      

     

     

     



     

  • 相关阅读:
    Ubuntu18.04 一条命令安装caffe问题
    ubuntu18 + caffe+cpu+anaconda3
    ubuntu18+caffe+cuda
    opencv-python常用接口
    tensorflow-gpu安装
    【LabVIEW】如何给输入控件赋值
    【LabVIEW】控件初始化
    【LabVIEW】程序结构
    【LabVIEW】程序框图中错误输出后status如何调出
    【总线】ARINC 429总线协议
  • 原文地址:https://www.cnblogs.com/cainame/p/11147153.html
Copyright © 2011-2022 走看看