精华内容
下载资源
问答
  • Java线程类也是一个object类,它的实例继承自java.lang.Thread或其子类。 可以用如下方式用java中创建一个线程:  Tread thread = new Thread();  执行该线程可以调用该线程的start()方法:  thread.start();...
  • Java创建线程的8种方式

    万次阅读 多人点赞 2018-07-21 21:16:51
    Java创建启动线程的多种方式 1、继承Thread类,重写run()方法 2、实现Runnable接口,重写run() 3、匿名内部类的方式 4、带返回值的线程(实现implements Callable<返回值类型>)————以上3...

     

    //方式1
    package cn.itcats.thread.Test1;
    
    public class Demo1 extends Thread{
    	
        //重写的是父类Thread的run()
    	public void run() {
    		System.out.println(getName()+"is running...");
    	}
    	
    	
    	public static void main(String[] args) {
    		Demo1 demo1 = new Demo1();
    		Demo1 demo2 = new Demo1();
    		demo1.start();
    		demo2.start();
    	}
    }
    
    • 2、实现Runnable接口,重写run()

    实现Runnable接口只是完成了线程任务的编写
    若要启动线程,需要new Thread(Runnable target),再有thread对象调用start()方法启动线程
    此处我们只是重写了Runnable接口的Run()方法,并未重写Thread类的run(),让我们看看Thread类run()的实现
    本质上也是调用了我们传进去的Runnale target对象的run()方法

    //Thread类源码中的run()方法
    //target为Thread 成员变量中的 private Runnable target;
    
     @Override
        public void run() {
            if (target != null) {
                target.run();
            }
        }

    所以第二种创建线程的实现代码如下:

    package cn.itcats.thread.Test1;
    
    /**
     * 第二种创建启动线程的方式
     * 实现Runnale接口
     * @author fatah
     */
    public class Demo2 implements Runnable{
    
        //重写的是Runnable接口的run()
    	public void run() {
    			System.out.println("implements Runnable is running");
    	}
    	
    	public static void main(String[] args) {
    		Thread thread1 = new Thread(new Demo2());
    		Thread thread2 = new Thread(new Demo2());
    		thread1.start();
    		thread2.start();
    	}
    
    }
    

    实现Runnable接口相比第一种继承Thread类的方式,使用了面向接口,将任务与线程进行分离,有利于解耦

    • 3、匿名内部类的方式

    适用于创建启动线程次数较少的环境,书写更加简便
    具体代码实现:

    package cn.itcats.thread.Test1;
    /**
     * 创建启动线程的第三种方式————匿名内部类
     * @author fatah
     */
    public class Demo3 {
    	public static void main(String[] args) {
    		//方式1:相当于继承了Thread类,作为子类重写run()实现
    		new Thread() {
    			public void run() {
    				System.out.println("匿名内部类创建线程方式1...");
    			};
    		}.start();
    		
    		
    		
    		//方式2:实现Runnable,Runnable作为匿名内部类
    		new Thread(new Runnable() {
    			public void run() {
    				System.out.println("匿名内部类创建线程方式2...");
    			}
    		} ).start();
    	}
    }
    
    • 4、带返回值的线程(实现implements  Callable<返回值类型>)

    以上两种方式,都没有返回值且都无法抛出异常。
    Callable和Runnbale一样代表着任务,只是Callable接口中不是run(),而是call()方法,但两者相似,即都表示执行任务,call()方法的返回值类型即为Callable接口的泛型
    具体代码实现:

    package cn.itcats.thread.Test1;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.Future;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.RunnableFuture;
    
    /**
     * 方式4:实现Callable<T> 接口
     * 含返回值且可抛出异常的线程创建启动方式
     * @author fatah
     */
    public class Demo5 implements Callable<String>{
    
    	public String call() throws Exception {
    		System.out.println("正在执行新建线程任务");
    		Thread.sleep(2000);
    		return "新建线程睡了2s后返回执行结果";
    	}
    
    	public static void main(String[] args) throws InterruptedException, ExecutionException {
    		Demo5 d = new Demo5();
    		/*	call()只是线程任务,对线程任务进行封装
    			class FutureTask<V> implements RunnableFuture<V>
    			interface RunnableFuture<V> extends Runnable, Future<V>
    		*/
    		FutureTask<String> task = new FutureTask<>(d);
    		Thread t = new Thread(task);
    		t.start();
    		System.out.println("提前完成任务...");
    		//获取任务执行后返回的结果
    		String result = task.get();
    		System.out.println("线程执行结果为"+result);
    	}
    	
    }
    
    • 5、定时器(java.util.Timer)

    关于Timmer的几个构造方法


    执行定时器任务使用的是schedule方法:


    具体代码实现:

    package cn.itcats.thread.Test1;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    /**
     * 方法5:创建启动线程之Timer定时任务
     * @author fatah
     */
    public class Demo6 {
    	public static void main(String[] args) {
    		Timer timer = new Timer();
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("定时任务延迟0(即立刻执行),每隔1000ms执行一次");
    			}
    		}, 0, 1000);
    	}
    	
    }
    

    我们发现Timer有不可控的缺点,当任务未执行完毕或我们每次想执行不同任务时候,实现起来比较麻烦。这里推荐一个比较优秀的开源作业调度框架“quartz”,在后期我可能会写一篇关于quartz的博文。

    • 6、线程池的实现(java.util.concurrent.Executor接口)

    降低了创建线程和销毁线程时间开销和资源浪费
    具体代码实现:

    package cn.itcats.thread.Test1;
    
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;
    
    public class Demo7 {
    	public static void main(String[] args) {
    		//创建带有5个线程的线程池
    		//返回的实际上是ExecutorService,而ExecutorService是Executor的子接口
    		Executor threadPool = Executors.newFixedThreadPool(5);
    		for(int i = 0 ;i < 10 ; i++) {
    			threadPool.execute(new Runnable() {
    				public void run() {
    					System.out.println(Thread.currentThread().getName()+" is running");
    				}
    			});
    		}
    		
    	}
    }
    

    运行结果:
    pool-1-thread-3 is running
    pool-1-thread-1 is running
    pool-1-thread-4 is running
    pool-1-thread-3 is running
    pool-1-thread-5 is running
    pool-1-thread-2 is running
    pool-1-thread-5 is running
    pool-1-thread-3 is running
    pool-1-thread-1 is running
    pool-1-thread-4 is running

    运行完毕,但程序并未停止,原因是线程池并未销毁,若想销毁调用threadPool.shutdown();    注意需要把我上面的
    Executor threadPool = Executors.newFixedThreadPool(10);              改为  
    ExecutorService threadPool = Executors.newFixedThreadPool(10);     否则无shutdown()方法

    若创建的是CachedThreadPool则不需要指定线程数量,线程数量多少取决于线程任务,不够用则创建线程,够用则回收。

    • 7、Lambda表达式的实现(parallelStream)

      package cn.itcats.thread.Test1;
      
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.List;
      
      /**
       * 使用Lambda表达式并行计算
       * parallelStream
       * @author fatah
       */
      public class Demo8 {
      	public static void main(String[] args) {
      		List<Integer> list = Arrays.asList(1,2,3,4,5,6);
      		Demo8 demo = new Demo8();
      		int result = demo.add(list);
      		System.out.println("计算后的结果为"+result);
      	}
      	
      	public int add(List<Integer> list) {
      		//若Lambda是串行执行,则应顺序打印
      		list.parallelStream().forEach(System.out :: println);
      		//Lambda有stream和parallelSteam(并行)
      		return list.parallelStream().mapToInt(i -> i).sum();
      	}
      }
      

      运行结果:
      4
      1
      3
      5
      6
      2
      计算后的结果为21
      事实证明是并行执行
       

    • 8、Spring实现多线程

    (1)新建Maven工程导入spring相关依赖
    (2)新建一个java配置类(注意需要开启@EnableAsync注解——支持异步任务)

    package cn.itcats.thread;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableAsync;
    
    @Configuration
    @ComponentScan("cn.itcats.thread")
    @EnableAsync
    public class Config {
    	
    }
    

    (3)书写异步执行的方法类(注意方法上需要有@Async——异步方法调用)

    package cn.itcats.thread;
    
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Service;
    
    @Service
    public class AsyncService {
    	
    	@Async
    	public void Async_A() {
    		System.out.println("Async_A is running");
    	}
    	
    	@Async
    	public void Async_B() {
    		System.out.println("Async_B is running");
    	}
    }
    

    (4)创建运行类

    package cn.itcats.thread;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class Run {
    	public static void main(String[] args) {
    		//构造方法传递Java配置类Config.class
    		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
    		AsyncService bean = ac.getBean(AsyncService.class);
    		bean.Async_A();
    		bean.Async_B();
    	}
    }
    

     

    展开全文
  • java课上老师要求的小练习,使用的是继承Thread类来实现的。
  • 如果我们run()在用户定义的线程重写方法,则在run()方法中,我们将定义一个作业,而我们创建线程负责执行run()方法。强烈建议您覆盖run()方法,因为它可以提高系统的性能。如果我们不在run()定义的线程重写...

    Java中的run()方法在Thread类中,run()方法是用空实现定义的。

    如果我们run()在用户定义的线程中重写方法,则在run()方法中,我们将定义一个作业,而我们创建的线程负责执行run()方法。

    强烈建议您覆盖run()方法,因为它可以提高系统的性能。

    如果我们不在run()定义的线程中重写Thread类方法,run()则将执行Thread类方法,并且由于Thread类run()的实现为空,因此不会获得任何输出。

    范例1:

    在这里,我们将看到,如果我们重写Thread类的run(),会发生什么?class OverrideRunMethod extends Thread{

    public void run(){

    System.out.println("I am in run() method");

    }

    }

    class MainMethodClass{

    public static void main(String[] args){

    OverrideRunMethod orn = new OverrideRunMethod();

    orn.start();

    }

    }

    输出结果D:\Java Articles>java MainMethodClass

    I am in run() method

    范例2:

    在这里,我们将看到,如果不重写Thread类run()会发生什么?abstract class NotOverridableRunMethod extends Thread{

    abstract public void run();

    }

    class ParentMain{

    public static void main(String[] args){

    OverrideRunMethod orn = new OverrideRunMethod();

    orn.start();

    System.out.println("Thread class run() method will be executed with empty implementation");

    }

    }

    当我们调用start()Thread类的方法时。它将执行一些任务,例如调用run()方法和分配线程调度程序等。run()如果run()方法不存在,首先将执行新创建的线程,然后将检查其父类(线程类)是否存在,然后run()将其方法执行。

    输出结果D:\Java Articles>java ParentMain

    Thread class run() method will be executed with empty implementation

    I am in run() method

    展开全文
  • java创建线程的4种方式

    千次阅读 2019-04-25 16:00:23
    java线程创建方式有几种?这种问题在面试中经常被问到,你可能心里马上反映出两种方式(实现Runnable、继承Thread),当你把这两种叙述给面试官听后,面试官会觉得你该掌握的知识已经有了,但是仅仅而已。如果你还说...

    写在前面的话

    java线程创建方式有几种?这种问题在面试中经常被问到,你可能心里马上反映出两种方式(实现Runnable、继承Thread),当你把这两种叙述给面试官听后,面试官会觉得你该掌握的知识已经有了,但是仅仅而已。如果你还说了callable与future、线程池,那么面试官就会认为你 知识覆盖面广,对你好感加一!下面首先叙述为什么会出现线程,以及线程在实际生活中的例子,紧接着给出四种创建线程的方式,加以代码进行演示。喜欢博主文章的你,动动你们的小爪子,点赞收藏呗(#^.^#)

    1、线程的知识

    1.1、什么是多线程

    百度百科这样说:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。好像和没说一样,概念还是不怎么理解。那就举个例子:早上小明起床后,需要完成刷牙、洗脸、烧水、听广播,为了节约时间、提高效率,小明边烧水、边听广播、边刷牙洗脸,这三个任务并行进行,就类似于三个线程。多线程就是同时多个线程同时工作,并发执行任务。

    1.2、为什么会有多线程

    这个问题可以转换为:多线程带来了什么好处与优势。结合《JAVA并发编程实践》总结如下:

    1、发挥多处理器的强大能力

    现在的处理器在频率上的提升空间越来越小,为了增加设备整体的性能,出现了多核多处理器设备。由于线程是cpu调度的基本单位, 当一个程序中只有一个线程时,最多只能在一个CPU上进行运行,其他CPU将处于空闲状态,严重影响多核CPU的性能。因此,如果涉及合理正确的多线程程序,将会充分利用多核CPU性能优势,提高整体设备性能。

    2、建模的简单性

    通过使用线程,可以将复杂并且异步的工作流进一步分解为一组简单并且同步的工作流,每个工作流在一个单独的线程中运行,并在特定的同步位置进行交互。我们可以通过一些现有框架来实现上述目标,例如Servlet和RMI,框架负责解决一些细节问题,例如请求管理、线程创建、负载平衡,并在正确的时候将请求分发给正确的应用程序组件。编写Servlet的开发人员不需要了解多少请求在同一时刻要被处理,也不需要了解套接字的输入流或输出流是否被阻塞,当调用Servlet的service方法来响应Web请求时,可以以同步的方式来处理这个请求,就好像它是一个单线程程序。

    3、异步事件的简化处理

    服务器应用程序在接受多个来自远程客户端的套接字连接请求时,如果为每个连接都分配其各自的线程并且使用同步I/O,那么就会降低这类程序的开发难度。如果某个应用程序对套接字执行读操作而此时还没有数据到来,那么这个读操作将一直阻塞,直到有数据到达。在单线程应用程序中,这不仅意味着在处理请求的过程中将停顿,而且还意味着在这个线程被阻塞期间,对所有请求的处理都将停顿。为了避免这个问题,单线程服务器应用程序必须使用非阻塞I/O,但是这种I/O的复杂性要远远高于同步I/O,并且很容易出错。然而,如果每个请求都拥有自己的处理线程,那么在处理某个请求时发生的阻塞将不会影响其他请求的处理。

    4、响应更灵敏的用户界面

    GUI界面采用多线程,可以同时响应多个按钮,比如在IDEA中,在程序运行时,还可以继续进行程序编写。

    1.3、线程与进程的区别

    进程是操作系统进行资源分配的单元,线程是CPU调度运行的单位;一个进程中可以包含很多线程,线程共享进程的内存等资源;每个进程拥有各自独立的一套变量,相互不影响,而线程则共享数据,会存在线程安全问题。

    1.4、举例说明线程与进程

    为了能够看到本地计算机上的线程信息,下载Process Explorer,解压运行进行查看。

     从上图可以形象的验证,进程与 线程之间的关系。关于Process Explorer的用法,感兴趣的可以自行研究。

    2、java创建线程的四种方式

    2.1、实现Runnable

    通过实现Runnable接口,重写run()方法。然后借助Thread的start()方法开启线程,调用run()方法是不会开启新线程的,只是一次方法调用而已。

    看一下Runnable接口的java代码,发现它只有一个run()方法。

    public interface Runnable {
        /**
         * When an object implementing interface <code>Runnable</code> is used
         * to create a thread, starting the thread causes the object's
         * <code>run</code> method to be called in that separately executing
         * thread.
         * <p>
         * The general contract of the method <code>run</code> is that it may
         * take any action whatsoever.
         *
         * @see     java.lang.Thread#run()
         */
        public abstract void run();
    }

    进行线程编写, 

    public class CreateThreads implements Runnable{
    
        @Override
        public void run() {
            System.out.println("通过实现Runnable接口开启线程~");
        }
    
        public static void main(String[] args) {
            CreateThreads createThreads = new CreateThreads();
            Thread thread = new Thread(createThreads);
            thread.start();
        }
    }

    2.2、继承Thread

    继承Thread类,重写run()方法。

    public class CreateThreads extends Thread{
    
        @Override
        public void run() {
            System.out.println("通过继承Thread开启线程~");
        }
    
        public static void main(String[] args) {
            CreateThreads createThreads = new CreateThreads();
            Thread thread = new Thread(createThreads);
            thread.start();
        }
    }

    注意:继承Thread类,重写run()方法,其本质上与实现Runnable接口的方式一致,因为Thread类本身就实现了Runnable接口

    public class Thread implements Runnable 。再加上java中多实现,单继承的特点,在选用上述两种方式创建线程时,应该首先考虑第一种(通过实现Runnable接口的方式)。

    2.3、通过Callable、Future

    通过Runnable与Thread的方式创建的线程,是没有返回值的。然而在有些情况下,往往需要其它线程计算得到的结果供给另外线程使用( 例如:计算1+100的值,开启三个线程,一个主线程,两个计算线程,主线程需要获取两个计算线程的结算结果(一个计算线程计算1+2+...+50,另外一个线程计算51+52+..+100),进行相加,从而得到累加结果),这个时候可以采用Runnable与Thread的方式创建的线程,并通过自行编写代码实现结果返回,但是不可避免的会出现黑多错误和性能上的问题。基于此,JUC(java.util.concurrent)提供了解决方案,实现Callable的call()方法(这个类似Runnable接口),使用Future的get()方法进行获取。

    下面首先看一下Callable接口:

    public interface Callable<V> {
        /**
         * Computes a result, or throws an exception if unable to do so.
         *
         * @return computed result
         * @throws Exception if unable to compute a result
         */
        V call() throws Exception;
    }

    下面开始使用Callable、与Future创建多线程。创建过程为:1、自定义一个类实现Callable接口,重写call()方法;2、使用JUC包下的ExecutorService生成一个对象,主要使用submit()方法,返回得到Future对象(关于JUC包下的诸如ExecutorService解析使用,请关注博主的后序文章);3、采用Future的get()获取返回值。

    import java.util.concurrent.*;
    
    /**
     * @author wolf
     * @create 2019-04-25    14:53
     * 计算1+...+100的结果,开启三个线程,主线程获取两个子线程计算的结果,一个子线程计算1+...+50,一个子线程计算51+...+100。
     */
    public class CreateThreads implements Callable {
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            //生成具有两个线程的线程池
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            //调用executorService.submit()方法获取Future
            Future<Integer> result1 = executorService.submit(new CreateThreads());
            Future<Integer> result2 = executorService.submit(new SubThread());
            //使用Future的get()方法等待子线程计算完成返回的结果
            int result = result1.get() + result2.get();
            //关闭线程池
            executorService.shutdown();
            //打印结果
            System.out.println(result);
    
        }
    
        //子线程1,用来计算1+...+50
        @Override
        public Object call() throws Exception {
            int count = 0;
            for (int i = 1; i <= 50; i++)
                count = count + i;
            return count;
        }
    }
    
    class SubThread implements Callable {
        //子线程2,用来计算51+...+100
        @Override
        public Object call() throws Exception {
            int count = 0;
            for (int i = 51; i <= 100; i++)
                count = count + i;
            return count;
        }
    }
    

    2.4、通过JUC里面的线程池

    JUC并发包里的 Executors工具类,提供了创建线程池的工厂方法,具体可以参看JDK的API。

    下面就Executors.newFixedThreadPool()说明,这里请移步2.3节的程序,会发现其实2.3节已经使用了Executors.newFixedThreadPool(2)构建线程池。

     

    3、总结

    通过上述叙述,希望对你知识掌握和面试有所帮助。多线程是java中的进阶,这一块还有很多知识点,本文后会继续发布关于多线程博客,旨在介绍java中多线程的框架,介绍JUC包,一起学习共勉。文中有错误的地方,还请留言给予指正,不胜感激~最后,喜欢博主的文章不妨关注点赞收藏哦,方便下次不走错门。

    展开全文
  • Java线程(二、创建线程

    千次阅读 2018-06-05 19:08:10
    今天来讲讲Java如何创建一个线程。大多数情况下,通过实例化一个Thread对象来创建一个线程Java定义了两种方式:实现Runnable接口继承Thread类实现Runnable接口创建线程的最简单的方法就是创建一个Runnable口的类。...

    今天来讲讲Java如何创建一个线程。

    大多数情况下,通过实例化一个Thread对象来创建一个线程,Java定义了两种方式:

    • 实现Runnable接口
    • 继承Thread类

    实现Runnable接口

    创建线程的最简单的方法就是创建一个Runnable口的类。Runnable抽象了一个执行代码单元。为实现Runnable接口,一个类仅需实现一个run()的简单方法,在run()方法中可以定义代码来构建新的线程。创建一个线程必须理解下面这段话:

    run()方法能够让主线程那样调用其他方法,引用其他类,声明变量。仅有的不同的是run()方法在程序中确立另一个并发的线程执行入口。当run()方法运行完毕时,该线程结束。

    在你已经创建了实现Runnable接口的类以后,你要在类内部实例化一个Thread类的对象。

    Thread(Runnable threadOb,String threadName)

    该构造函数中,threadOb时一个实现Runnable接口的实现类,threadName参数则是你新建线程的线程名称,这定义了线程执行的起点。

    建立了新的线程,它并不能运行,需要调用start方法来执行线程的run()方法。本质上,start()方法执行的是一个对run()的调用。

    public class Test1 {
    
        public static void main(String[] args) throws InterruptedException {
            new XkThread();
            try {
                for(int i=1;i<=5;i++){
                    Thread.currentThread().sleep(1000);//让当前线程睡眠1秒    
                    System.out.println("大家好,我是主线程:"+i);
                }
                //需要捕获sleep()方法可能抛出的异常
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    class XkThread implements Runnable {
        private Thread th;
    
        public XkThread() {
            th=new Thread(this);
            System.out.println("开始调用run()方法");
            th.start();//调用run()方法
        }
        @Override
        public void run() {
            try {
                for(int i=1;i<=5;i++){
                    th.sleep(1000);//让线程睡眠1秒    
                    System.out.println("大家好,我是子线程:"+i);
                }
                //需要捕获sleep()方法可能抛出的异常
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
        }
        
    }
    
    
    

    在NewThread中构造函数中,新的Thread对象由下面语句创建:

    th=new Thread(this);

    通过前面的语句this表明了在this对象中你想要新的线程调用run()方法。然后start()被调用,以run()方法为开始启动了线程的执行。这使子线程for循环开始执行。调用start()方法之后,NewThread的构造函数返回到main()。当主线程被恢复,主线程开始执行自己的for循环。两个线程同时运行,共享CPU,直到它们的循环结束。

    运行结果:

    开始调用run()方法
    大家好,我是主线程:1
    大家好,我是子线程:1
    大家好,我是子线程:2
    大家好,我是主线程:2
    大家好,我是子线程:3
    大家好,我是主线程:3
    //省略
    

    继承Thread类

    创建线程的另一个途径就是继承Thread类,然后创建子类的实例。当一个类继承Thread类时,它必须重写run()方法,这个run()方法时新线程的入口。它也必须调用start()方法来启用新线程执行。

    public class Test2 {
    
    	public static void main(String[] args) {
    		new MyThread("child Thread");
    		System.out.println("开始执行主线程的for循环");
    		try {
    			for(int i=1;i<=5;i++){
    				Thread.currentThread().sleep(1000);//让主线程睡眠1秒	
    				System.out.println("大家好,我是主线程:"+i);
    			}
    			//需要捕获sleep()方法可能抛出的异常
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }
    class MyThread extends Thread{
    
    	public MyThread(String threadName) {
    		super(threadName);
    		System.out.println("开始调用start()方法");
    		start();
    	}
    	
    	@Override
    	public void run() {
    		System.out.println("开始执行子线程的for循环");
    		try {
    			for(int i=1;i<=5;i++){
    				sleep(500);//让子线程睡眠0.5秒	
    				System.out.println("大家好,我是子线程:"+i);
    			}
    			//需要捕获sleep()方法可能抛出的异常
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    	
    }

    创建一个子线程MtThread,在构造函数中调用start()方法启动子线程,然后主线程也继续运行,为了让主线程最后结束,在这里我让子线程睡眠时间为0.5秒,主线程睡眠时间为1秒,这样子总可以让主线程最后结束。

    运行结果:

    开始调用start()方法
    开始执行主线程的for循环
    开始执行子线程的for循环
    大家好,我是子线程:1
    大家好,我是子线程:2
    大家好,我是主线程:1
    大家好,我是子线程:3
    大家好,我是主线程:2
    大家好,我是子线程:4
    大家好,我是子线程:5
    大家好,我是主线程:3
    大家好,我是主线程:4
    大家好,我是主线程:5
    

    最后

    到这里,你一定很奇怪为什么Java有两种创建子线程的方法呢?哪一种更好呢?所有的问题都归于一点,Thread类定义了多种方法可以被子类重载。对于所有的方法,唯一的必须重写的是run()方法。而实现Runnable接口也只需要重写run()方法。因此,如果你不重载Thread的其他方法,最好是实现Runnable接口。当然了,这得看个人习惯。


    展开全文
  • java线程示例

    2017-03-02 14:03:46
    Java中的多线程有三种实现方式: 1.继承Thread类,重写run方法。Thread本质上也是一个实现了Runnable的实例,他代表一个线程的实例,并且启动线程的唯一方法就是通过Thread类的start方法。 2.实现Runnable接口,并...
  • Java中如何创建线程

    千次阅读 2019-03-17 07:54:46
    进程,每个正在系统上运行的程序是一个进程。 线程线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行,每个进程包含一到多个线程。 多线程的好处(类比同步跟异步的概念) ☞ 提高执行任务...
  • Java线程创建与启动

    2020-12-22 20:44:10
    SCJP5学习笔记  一、定义线程  1、扩展java.lang.Thread类。  此类中有个run()方法,...  使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的 run 方法。  方法 r
  • java创建线程的四种方式及其区别

    千次阅读 2019-04-26 18:35:25
    java创建线程有如下四种方式: 继承Thread类创建线程 实现Runnable接口创建线程 使用Callable和Future创建线程 使用线程池创建(使用java.util.concurrent.Executor接口) 下面分别介绍这四种创建线程的方式...
  • 昨天有个小伙伴去阿里面试实习生岗位,面试官问他了一个老生常谈的问题:你说一说 Java 创建线程都有哪些方式? 这哥们心中窃喜,这个老生常谈的问题早已背的滚瓜烂熟,于是很流利的说了出来。 Java 创建线程有两种...
  • 如何创建、启动 Java 线程

    千次阅读 2019-09-02 10:19:18
    Java 中有 4 种常见的创建线程的方式。 一、重写 Thread 类的 run() 方法。 表现形式有两种:1)new Thread 对象匿名重写 run() 方法 package constxiong.concurrency.a006; /** * new Thread 对象匿名重写 ...
  • java 创建线程的三种方式、创建线程池的四种方式

    万次阅读 多人点赞 2019-02-23 21:01:44
    java创建线程的三种方式: 继承Thread类创建线程类 实现Runnable接口 通过Callable和Future创建线程 java创建线程池的四种方式: newCachedThreadPool 创建一个可缓存的线程池,如果线程池长度超过处理...
  • Java线程之如何创建线程

    千次阅读 2018-05-24 13:41:34
    Java与多线程的关系我们平时写的好多简单程序就有多个线程参与,你可能会感到惊讶,但是事实就是这样。Java程序从main()方法开始执行,然后按照既定的代码逻辑执行,看似没有其他线程参与,但实际上Java程序天生就是...
  • Java线程-1】线程概述与线程创建和使用

    万次阅读 多人点赞 2019-11-02 17:04:48
    例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才...
  • Java创建线程及配合使用Lambda

    万次阅读 2018-08-30 16:32:13
    说明Java创建线程的三种方式,以及在创建线程的时候利用Lambda简化代码的实现
  • Java中,用Thread类代表线程,所有线程对象,必须是Thread类或者Thread类子类的实例 多线程创建方式有三种,但是今天我只介绍两种经常用的方式: 第一种创建方式: 继承Thread类,并重写run()方法  第一步:...
  • java常见创建线程的三种方式

    千次阅读 2021-06-11 15:38:06
    创建线程的方法主要有如下三种: 方式1]继承Thread类创建线程 //使用方法1:继承Thread,重写其run()方法 new MyThread().start(); //使用方法2:创建匿名内部类Thread,重写其run()方法 new Thread() { @...
  • JAVA线程的三种创建方式

    万次阅读 多人点赞 2019-03-03 16:24:47
    JAVA中,用Thread类代表线程,所有线程对象,必须是Thread类或者Thread类子类的实例。每个线程的任务就是执行一段顺序执行的代码,JAVA使用线程执行体来容纳这段代码。所以,我们创建线程时,主要是根据实际...
  • java线程之继承Thread类实现创建线程1.Java线程之Thread类2.继承Thread类实现创建线程3.Thread类常用的方法 1.Java线程之Thread类 Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread类...
  • java.lang.Thread类:是描述线程的类,我们想要实现多线程程序,就必须继承Thread类。 实现步骤: 创建一个Thread类的子类。 在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么?)。 ...
  • java创建线程最简单的方式

    千次阅读 2018-04-08 14:19:50
    在开发项目中,偶尔会用到线程,众所周知,线程有2种创建方式:继承Thread类和实现Runnable接口,具体实现过程如下一,继承Thread类,过程如下:(1)定义Thread类的子类,并重写父类的run()方法,方法里的内容就是线程所要...
  • JAVA中,用Thread类代表线程,所有线程对象,必须是Thread类或者Thread类子类的实例。每个线程的任务就是执行一段顺序执行的代码,JAVA使用线程执行体来容纳这段代码 二、多线程的好处 1.充分利用CPU资源 2.简化...
  • 这是一道面试题,创建线程时,使用继承Thread类和实现Runnable接口有哪些区别呢? 一、Thread 先来看看Thread类和其中的start()方法 class Thread implements Runnable{.....} // 可见,Thread类实现了Runnable...
  • 前面学习了创建线程的两种方式: 1)继承Thread类 2)实现Runnable接口 这两种方式有如下缺点: 1)没有返回值 2)不支持泛型 3)异常必须处理 实现多线程的第三种方式: 实现Callable接口,重写call方法 ...
  • Java线程超详解

    万次阅读 多人点赞 2019-06-11 01:00:30
    引言 随着计算机的配置越来越高,我们需要将进程进一步优化,细分为线程,充分提高图形化界面的多线程的开发。这就要求对线程的掌握很彻底。 那么话不多说,今天本帅将记录...2.run():通常需要重写Thread类中的此...
  • 创建Java线程的三种方式前言线程闲谈(可跳过)创建线程的三种方式继承Thread类重写run()方法实现Runnable接口实现Callable接口小结 前言 因为这段时间主要在学习多线程和MySQL的一些知识,所以整理一下Java多线程的...
  • Java线程怎样映射到操作系统线程

    千次阅读 2019-04-06 22:07:31
    先说多线程模型,参考经典教材《Operating System Concepts , Silberschatz ,9th edition》 中文版是《操作系统概念,第9版》 https://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/4_Threads.html 一...
  • Java创建并执行线程的四种方法

    万次阅读 多人点赞 2017-10-04 23:00:14
    java里面创建线程有四种方式: 无返回: 1. 实现Runnable接口,重写run(); 2. 继承Thread类,重写run(); 有返回: 1. 实现Callable接口,重写call(),利用FutureTask包装Callable,并作为task传入Thread构造函数...
  • Java线程的实现方式详解(Java基础)

    千次阅读 多人点赞 2020-05-29 18:15:48
    你好我是辰兮,很高兴你能来阅读,本篇为Java基础之多线程的实现讲解,基础知识的讲解,相关的更多,面试知识已经提前整理好...创建线程的方式一致为Java面试常见基础问题,基础学习中我们常用前两种方式,下文带大.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 188,627
精华内容 75,450
关键字:

创建java线程都需要重写

java 订阅
友情链接: OverlappedServer.rar