精华内容
下载资源
问答
  • java创建线程的方式
    千次阅读
    2022-06-05 22:10:43

    一、java中线程的创建方式

    在Java中,创建线程主要有三种方式,即继承Thread类,实现Runnable接口,实现Callable接口,一个继承,两个实现。

    1. 继承Thread类

    写一个类MyThread,继承Thread类,覆写run()方法,创建Thread子类实例thread,通过thread调用start()启动线程。

    public class MyThread extends Thread{
        @Override // 实现Thread类,覆写run方法
        public void run() {
            System.out.println("继承Thread方式");
            // ... 具体业务逻辑
        }
    
        public static void main(String[] args) {
            MyThread thread = new MyThread();
            thread.start(); // 启动线程
        }
    }
    

    2. 实现Runnable接口

    写一个类MyRunnable实现RUnnable接口,覆写run()方法,创建MyRunnable对象runnable,将runnable作为参数调用Thread有参构造,创建线程thread,调用start()启动线程。

    public class MyRunnable implements Runnable{
        @Override
        public void run() {
            System.out.println("实现Runnable接口方式");
            // ...具体业务逻辑
        }
    
        public static void main(String[] args) {
            // 创建Runnable实现类对象
            MyRunnable runnable = new MyRunnable();
            // 将runnable作为参数,调用Thread有参构造得到线程
            Thread thread = new Thread(runnable);
            thread.start(); // 启动线程
        }
    }
    

    3. 实现Callable接口

    写一个类MyCallable实现Callable接口,覆写call方法(返回值为Callable泛型),然后创建实现类对象callable,再创建FutureTask对象,将callable作为参数传入,得到对象futureTask,再创建Thread对象,将futureTask作为参数传入,调用start方法启动线程。想要获得线程执行后的返回值,用futureTask调用get()方法,获取返回值。

    public class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println("实现Callable接口方式");
            // ... 具体业务逻辑
            return "返回值"; // 返回值,类型和Callable泛型一致,这里用String举例
        }
    
        public static void main(String[] args) {
            // 创建Callable实现类对象
            MyCallable callable = new MyCallable();
            // 将callable作为参数创建FutureTask对象
            FutureTask<String> futureTask = new FutureTask<>(callable);
            // 将futureTask作为参数创建线程
            Thread thread = new Thread(futureTask);
            thread.start(); // 启动线程
            try {
                // 获取线程执行后的返回值
                String result = futureTask.get();
                System.out.println(result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    二、线程创建三种方式对比

    1. 继承和实现的区别,单继承多实现,实现扩展性更强。
    2. 三者创建线程的写法不同。
    3. 集成Thread和实现Runnable没有返回值,且覆写的run()方法。实现Callable方式,覆写的call()方法,有返回值,对应泛型。

    注意:
    调用start()才是启动线程,如果只是调用run()或者call()方法,都只是调用实例方法,并不是启动线程。

    更多相关内容
  • java创建线程的四种方式

    千次阅读 2022-03-14 11:52:41
    4.使用线程池创建线程 1.直接初始化Thead类,实现Runnable接口 查看Thread类源码可以发现,有下面这么一个构造参数,target是线程启动的时候要调用的方法(Runnable接口中有个run方法),如果为空,那这个类的运行...

    目录

    1.直接初始化Thead类,实现Runnable接口

    2.继承Thread类

    3.实现callable接口

    4.使用线程池创建线程


    1.直接初始化Thead类,实现Runnable接口

    查看Thread类源码可以发现,有下面这么一个构造参数,target是线程启动的时候要调用的方法(Runnable接口中有个run方法),如果为空,那这个类的运行方法什么都不做

    那我们是否可以直接初始化线程,然后调用start方法启动呢

    答案是可以的

        public Thread(Runnable target) {
            init(null, target, "Thread-" + nextThreadNum(), 0);
        }

    测试代码如下

        public static void main(String args[]){
            new Thread(new Runnable(){
    
                @Override
                public void run() {
                    System.out.println("test create thread by Runable");
                }
            }).start();
        }
        
    Connected to the target VM, address: '127.0.0.1:57009', transport: 'socket'
    test create thread by Runable
    Disconnected from the target VM, address: '127.0.0.1:57009', transport: 'socket'

    当然我们也可以写一个类去实现Runnable接口

    测试代码如下

    class Demo implements Runnable{
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }
    
    public static void main(String args[]) {
        Demo d = new Demo();
        Thread thread1 = new Thread(d,"first thread");
        Thread thread2 = new Thread(d,"second thread");
        thread1.start();
        thread2.start();
    }
        
    Connected to the target VM, address: '127.0.0.1:65445', transport: 'socket'
    second thread
    first thread
    Disconnected from the target VM, address: '127.0.0.1:65445', transport: 'socket'

    上面这种方式只new了一个Demo,所以thread1和thread2会共享类中的局部变量

    我们测试下这种方式共享局部变量的效果,可以仔细看看count这个变量的变化,每个线程不是10->1这么变化的,说明count这个变量被2个线程共享了

    class Demo implements Runnable{
    
        private int count =10;
        @Override
        public void run() {
            for(int i=0;i<10;i++){
                System.out.println(Thread.currentThread().getName()+count--);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
        }
    }
    
    public static void main(String args[]) {
        Demo d = new Demo();
        Thread thread1 = new Thread(d,"first thread");
        Thread thread2 = new Thread(d,"second thread");
        thread1.start();
        thread2.start();
    }
    
    Connected to the target VM, address: '127.0.0.1:51427', transport: 'socket'
    first thread10
    second thread9
    first thread8
    second thread7
    second thread6
    first thread5
    second thread4
    first thread3
    first thread2
    second thread2
    first thread1
    second thread1
    second thread0
    first thread-1
    second thread-2
    first thread-3
    second thread-4
    first thread-5
    second thread-6
    first thread-7
    Disconnected from the target VM, address: '127.0.0.1:51427', transport: 'socket'
    
    Process finished with exit code 0
    

    如果我们不想共享类中的变量,那只能初始化2个Demo类,代码如下

    public static void main(String args[]) {
        Demo d1 = new Demo();
        Demo d2 = new Demo();
        Thread thread1 = new Thread(d1,"first thread");
        Thread thread2 = new Thread(d2,"second thread");
        thread1.start();
        thread2.start();
    }
    
    Connected to the target VM, address: '127.0.0.1:65346', transport: 'socket'
    first thread10
    second thread10
    first thread9
    second thread9
    second thread8
    first thread8
    first thread7
    second thread7
    first thread6
    second thread6
    first thread5
    second thread5
    first thread4
    second thread4
    first thread3
    second thread3
    first thread2
    second thread2
    first thread1
    second thread1
    Disconnected from the target VM, address: '127.0.0.1:65346', transport: 'socket'

    2.继承Thread类

    前面我们通过初始化Thread类的方式创建线程,那我们是否可以新建一个类继承Thread类,然后创建线程呢,那肯定是可以的

    测试代码如下

    class Demo extends Thread{
    
        public void run() {
            System.out.println(Thread.currentThread().getName());
    
        }
    }
    
    public static void main(String args[]) {
        Demo d = new Demo();
        Thread thread1 = new Thread(d,"create thread by extends Thread");
        thread1.start();
    }
    
    Connected to the target VM, address: '127.0.0.1:64623', transport: 'socket'
    create thread by extends Thread
    Disconnected from the target VM, address: '127.0.0.1:64623', transport: 'socket'

    3.实现callable接口

    A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call. The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.(返回结果并可能抛出异常的任务。实现者定义了一个不带参数的方法,称为call。 Callable接口与Runnable接口类似,两者都是为其实例可能由另一个线程执行的类设计的。然而,Runnable不返回结果,也不能抛出检查异常。)

    我们查看jdk中callable类的注释,可以知道几个关键的信息

    1.Callable接口和Runnable接口类似,都是为其他线程执行实例而设计的

    2.Callable可以接受结果

    3.Callable可以检查异常

    通过jdk的FutureTask类,我们可以看到其实现了RunableFuture接口,然后这个接口是继承的Runable

    我们来看一下他的源码

    我们可以通过这个方法来实例化FutureTask

    Creates a FutureTask that will, upon running, execute the given Callable. Params: callable – the callable task Throws: NullPointerException – if the callable is null

    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

    然后通过get方法获取返回结果

    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

    Returns result or throws exception for completed task. Params: s – completed state value

    private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }

    测试代码如下

    class Demo implements Callable{
    
        @Override
        public Object call() throws Exception {
            int sum=0;
            for(int i=0;i<10;i++){
                sum=sum+i;
                Thread.sleep(300);
            }
            System.out.println("sum:"+sum);
            return sum;
        }
    }
    
    
    public static void main(String args[]) throws Exception{
    
        System.out.println("time1:"+new Date());
        Demo d = new Demo();
        FutureTask futureTask = new FutureTask(d);
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println("time2:"+new Date());
        Object sum = futureTask.get(5,TimeUnit.SECONDS);
        System.out.println("time3:"+new Date());
        System.out.println(sum);
    
    }
    
    Connected to the target VM, address: '127.0.0.1:60755', transport: 'socket'
    time1:Fri Mar 11 17:54:19 CST 2022
    time2:Fri Mar 11 17:54:19 CST 2022
    sum:45
    time3:Fri Mar 11 17:54:22 CST 2022
    45
    Disconnected from the target VM, address: '127.0.0.1:60755', transport: 'socket'

    我们可以发现time2和time3之间间隔了3s,然后获得了结果

    4.使用线程池创建线程

    线程池创建线程的优点

    Thread pools address two different problems: they usually provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and managing the resources, including threads, consumed when executing a collection of tasks. Each ThreadPoolExecutor also maintains some basic statistics, such as the number of completed tasks.(线程池解决两个不同的问题:它们通常在执行大量异步任务时提高性能,因为减少了每个任务的调用开销,并且它们提供了一种方法来限制和管理执行任务集合时消耗的资源(包括线程)。每个ThreadPoolExecutor还维护一些基本的统计信息,比如完成任务的数量。)

    1.使用ThreadPoolExecutor创建线程.这种方式比较灵活

    Params:

    • corePoolSize – the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set
    • maximumPoolSize – the maximum number of threads to allow in the pool
    • keepAliveTime – when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.
    • unit – the time unit for the keepAliveTime argument
    • workQueue – the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.
    • threadFactory – the factory to use when the executor creates a new thread
    • handler – the handler to use when execution is blocked because the thread bounds and queue capacities are reached
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

    下面我们来测试一下,这里使用callable,当然也可以使用runnable

    class Demo implements Callable{
    
        @Override
        public Object call() throws Exception {
            int sum=0;
            for(int i=0;i<10;i++){
                sum=sum+i;
                Thread.sleep(300);
            }
            System.out.println("sum:"+sum);
            return sum;
        }
    }
    
        public static void main(String args[]) throws Exception{
    
            ThreadPoolExecutor pool = new ThreadPoolExecutor(10,20,60L,TimeUnit.SECONDS,new SynchronousQueue<>(), new ThreadFactoryBuilder().setNameFormat("test thread pool").build(),new ThreadPoolExecutor.AbortPolicy());
            Demo d = new Demo();
            Future f = pool.submit(d);
            System.out.println("当前时间:"+new Date());
            Object result = f.get(5L,TimeUnit.SECONDS);
            System.out.println("当前时间:"+new Date()+"==结果:"+result);
        }
        
    当前时间:Mon Mar 14 11:28:42 CST 2022
    sum:45
    当前时间:Mon Mar 14 11:28:45 CST 2022==结果:45

    2.使用Executors创建线程池

    这种方法比较简单,其实就是对上面的方法进行了一些封装,建议使用上面的方法,因为可以看到具体的参数

    Executorst提供了几个常见构造方法

    • newFixedThreadPool--
    • newSingleThreadExecutor
    • newCachedThreadPool
    • newScheduledThreadPool

    我们来找一个这个类的构造参数看一下

    Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.
    Params:
    nThreads – the number of threads in the pool
    Returns:
    the newly created thread pool
    Throws:
    IllegalArgumentException – if nThreads <= 0

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

    测试一下

    class Demo implements Runnable{
    
        @Override
        public void run() {
            int sum=0;
            for(int i=0;i<10;i++){
                sum=sum+i;
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("sum:"+sum);
    
        }
    }
    
        public static void main(String args[]) throws Exception{
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            Demo d = new Demo();
            executorService.submit(d);
        }
        
    Connected to the target VM, address: '127.0.0.1:55962', transport: 'socket'
    sum:45
    Disconnected from the target VM, address: '127.0.0.1:55962', transport: 'socket'

    展开全文
  • Java创建线程

    千次阅读 多人点赞 2022-04-05 22:49:44
    既然说到线程,在这里就给大家普及一下线程线程(Thread): 是操作系统能够进行运算调度的最小单位。 它被包含在进程之中,是进程中的实际运作单位。 一个线程指的是进程中一个单一顺序的控制流。 ...

    目录

    既然说到线程,在这里就给大家普及一下线程。

    线程(Thread):

    那么,进程是什么呢?

    接下来,就让我们步入主题:

    在 Java 中,是这样说线程的:

    创建一个新的执行线程有两种方法。 

    第一种:创建一个类实现 Thread 类

     创建线程的第二种方式:使用 Thread(Runnable target) 构造方法,创建对象


    既然说到线程,在这里就给大家普及一下线程。

    🎇🎇🎇🎇🎇🎇🎇🎇

    线程(Thread):

    • 是操作系统能够进行运算调度的最小单位。
    • 它被包含在进程之中,是进程中的实际运作单位。
    • 一个线程指的是进程中一个单一顺序的控制流。

    🥂🥂🥂

    其实:进程在我们计算机中我们随时都在使用:按住 Ctrl + shift + esc

    watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA546L5L2z5Lyf4pmq,size_16,color_FFFFFF,t_70,g_se,x_16

    这个就是一个进程,在计算机中,线程就是进程中的一个执行单元。

    那么,进程是什么呢?

    进程:简简单单,我们日常中使用的QQ就是一个进程进程可以理解为就是一个软件,线程则就是这个软件中的一些功能,多个线程同时工作,才能使得进程工作。🤔🤔🤔。

    使用官方的话来描述进程:

    是计算机中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配与调度的基本单位。

    接下来,就让我们步入主题:

    ⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰

    在 Java 中,是这样说线程的:

    Java中,Thread类定义为:继承 了祖先类 Object ,实现了 Runable 接口。

    public class Thread extends Object implements Runnable

    线程是程序(进程)中执行的线程。

    Java虚拟机允许应用程序同时执行多个执行线程。 


    每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行。 每个线程可能也可能不会被标记为守护程序。 当在某个线程中运行的代码创建一个新的Thread对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护线程。 

    当Java虚拟机启动时,通常有一个非守护进程线程(通常调用某些指定类的名为main的方法)。 Java虚拟机将继续执行线程,直到发生以下任一情况: 

    已经调用了Runtime类的exit方法,并且安全管理器已经允许进行退出操作。 
    所有不是守护进程线程的线程都已经死亡,无论是从调用返回到run方法还是抛出超出run方法的run 。 


    创建一个新的执行线程有两种方法。 

    第一种:创建一个类实现 Thread 类

    package stu.my.cdn.creadthread.p1;
    
    /**
     * 创建线程的第一种方式:创建类,实现 Thread 方法
     */
    public class MyThread extends Thread {
    
        /**
         * run () 方法就是子线程要执行的代码
         */
        @Override
        public void run() {
            System.out.println("这是子线程打印的东西");
        }
    
        /**
         * 主线程 main
         */
        public static void main(String [] args) {
            System.out.println("JVM 启动 main线程,main线程执行了main方法");
            // 创建子线程对象
            MyThread thread = new MyThread();
            // 启动线程----启动线程后,会自动执行自定义类中的 run 方法
            thread.start();
            System.out.println("mian 主线程执行结束");
        }
    }
    

     以下是程序的输出结果:

    watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA546L5L2z5Lyf4pmq,size_20,color_FFFFFF,t_70,g_se,x_16

    这种程序执行分为三种方式:

    串行:特殊的并行,程序排队执行,比较耗时,但安全。 

    并发:一个程序执行,在等待阶段,下一个开始。

    并行:简单粗暴,程序一起开始执行,一般效率高。

    从硬件角度来说:如果是单核 CPU ,一个处理器一次只能执行一个线程的情况下,处理器可以使用时间片轮转技术,可以让 CPU 快速的在各个线程之间进行切换,对用户来说,感觉是三个线程在同时执行,如果是多核 CPU ,可以为不同的线程分配不同的 CPU 内核。

    package stu.my.cdn.creadthread.p2;
    
    public class MyThread2 extends Thread{
    
        @Override
        public void run() {
            // 处理异常快捷键 ,选中代码: Ctrl + Alt + T
            try {
                for(int i = 1; i <= 5; i++){
                    System.out.println("子线程==>" + i);
                    int time = (int) (Math.random() * 1000);
                    Thread.sleep(time);     // 线程睡觉,单位是 毫秒, 1s = 1000ms
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            MyThread2 myThread2 = new MyThread2();
            myThread2.start();      // 开启子线程
    
            try {
                for(int i = 1; i <= 5; i++){
                    System.out.println("主线程main==>" + i);
                    int time = (int) (Math.random() * 1000);
                    Thread.sleep(time);     // 线程睡觉,单位是 毫秒, 1s = 1000ms
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

     第一次执行顺序:

     watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA546L5L2z5Lyf4pmq,size_20,color_FFFFFF,t_70,g_se,x_16

    第二次执行顺序 :

     watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA546L5L2z5Lyf4pmq,size_20,color_FFFFFF,t_70,g_se,x_16

    fb528211efe249a6887c1003042963df.gif

     创建线程的第二种方式:使用 Thread(Runnable target) 构造方法,创建对象

    如果已经类已经有了继承的父类,则第一种方式便不再使用这种情况,(因为在JAVA中一个类只能有一个父类):🤔🤔🤔🤔

     那我们便可以使用这种方式:实现接口,使用构造方法,创建线程:

     watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA546L5L2z5Lyf4pmq,size_17,color_FFFFFF,t_70,g_se,x_16

    package stu.my.cdn.creadthread.p3;
    
    /**
     * 当线程已经有父类了,就不能继承 Thread 类的形式创建线程了,可以使用 Runnable 接口的形式
     */
    public class MyRunnable implements  Runnable{
        /**
        * 这里的 run 方法 就相当于我们日常中使用的 main 方法
        * 一旦 线程 start() 就会执行这个方法 
        */
        @Override
        public void run() {
            for(int i = 0; i <= 5; i++){
                System.out.println("MyRunnable implements Runnable 's run method:" + i);
            }
        }
    
        public static void main(String[] args) {
            // 创建 Runnable 接口的实现类
            MyRunnable myRunnable = new MyRunnable();
            // 使用 Runnable 的 Thread(Runnable target) 方法,创建线程对象
            Thread thread = new Thread(myRunnable);
            // 开启线程
            thread.start();
    
            // main 线程
            for (int i = 1; i <= 5; i++){
                System.out.println("Runnable is main:" +i);;
            }
    
            // 使用匿名内部内实现
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int i = 0; i < 5; i++){
                        System.out.println("use anonymous interior class finished thread create :" + i);
                    }
                }
            });
            // 开启 thread1
            thread1.start();
        }
    }
    

     一样,线程每次并行执行,根据 CPU 核数的不同和允许执行线程的数量,利用对应的技术,在各个线程之间切换,提高执行的效率。

     watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA546L5L2z5Lyf4pmq,size_20,color_FFFFFF,t_70,g_se,x_16

     本期就到这里~~~

    感谢大家阅读~~~68739b582cce4a7289d1d9dede0f0f48.gif

    展开全文
  • ======创建线程方式====== 继承Thead类,重写run()方法 实现Runnable类,重写run()方法 使用lombda 实现Callable类,重写call()方法 使用线程池 ======停止线程的方式====== 使用stop()方法 使用suspend()和resume()...

    创建线程

    方式1 - 继承Thead类,重写run()方法

    public class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println("线程操作");
        }
    }
    
    public static void main(String[] args) throws Exception {
        new MyThread().start();
    }
    

    方式2 - 实现Runnable类,重写run()方法

    public class MyRunnable implements Runnable{
        @Override
        public void run() {
            System.out.println("线程操作");
        }
    }
    
    public static void main(String[] args) throws Exception {
        new Thread(new MyRunnable()).start();
    }
    

    方式3 - 使用lombda

    public static void main(String[] args) throws Exception {
        new Thread(() -> {
            System.out.println("线程操作");
        }).start();
    }
    

    方式4 - 实现Callable类,重写call()方法

    public class MyCallable implements Callable<String>{
        @Override
        public String call() throws Exception {
            System.out.println("线程操作");
            return "call";
        }
    }
    
    public static void main(String[] args) throws Exception {
        FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
        new Thread(futureTask).start();
        // 获取call()的返回值,此方法会阻塞
        futureTask.get();
    }
    

    方式5 - 使用线程池

    public class MyRunnable implements Runnable{
        @Override
        public void run() {
            System.out.println("线程操作");
        }
    }
    
    public class MyCallable implements Callable<String>{
        @Override
        public String call() throws Exception {
            System.out.println("线程操作");
            return "call";
        }
    }
    
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new MyRunnable());
        Future future = executorService.submit(new FutureTask<>(new MyCallable()));
    	future.get();
    }
    

    停止线程

    方式1 - 使用stop()方法

    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            while (true) {
                System.out.println("线程操作");
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
        Thread.sleep(500);
        // 停止线程
        thread.stop();
    }
    

    方式2 - 使用suspend()和resume()方法

    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            while (true) {
                System.out.println("线程操作");
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
        Thread.sleep(500);
        // 暂停线程
    	thread.suspend();
    	// 恢复线程执行
    	thread.resume();
    }
    

    方式3 - 配合volatile

    private static volatile boolean isStop = false;
    
    public static class MyRunnable implements Runnable {
        @Override
        public void run() {
            while (!isStop) {
                System.out.println("线程操作");
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
        Thread.sleep(500);
        // 修改变量
        isStop = true;
    }
    

    方式4 - 使用interrupt()方法

    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                System.out.println("线程操作");
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
        Thread.sleep(500);
        // 打断线程
        thread.interrupt();
    }
    

    方式5 - 什么都不做,让线程自然结束

    public static class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("线程操作");
        }
    }
    
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
    }
    
    展开全文
  • java创建线程(Thread)的5种方式

    千次阅读 2021-01-16 17:07:50
    java创建线程(Thread)的4种方式方式一:继承于Thread类方式二:实现Runnable接口方式三:实现Callable接口方式四:使用线程池 方式一:继承于Thread类 步骤: 1.创建一个继承于Thread类的子类 2.重写Thread类的...
  • Java创建线程的三种方式

    千次阅读 2022-03-11 15:51:32
    1.通过继承Thread类创建线程,需要重写run()方法,通过start()开启线程 package com.MyThread; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; ...
  • 基本概念: 程序(program):是为完成特定任务、用某种语言编写的一组...线程作为调度和执行的单位,每个线程都拥有独立的运行栈和程序计数器,一个进程中的多个线程共享相同的内存单元/内存地址空间——>他们从
  • Java创建线程的四种方式

    万次阅读 多人点赞 2018-07-28 22:10:16
    1.继承Thread类实现多线程  run()为线程类的核心方法,相当于主线程的main方法,是每个线程的入口  a.一个线程调用 两次start()方法将会抛出线程状态异常,也就是的start()只可以被调用一次   b.native生明的...
  • 一、创建线程方式 方式一:继承Thread类 1)① 新建一个类,这个类继承了Thread,此时这个实现类就是一个线程类了。② 在线程类中重写Thread类的run()方法,重写的run方法中是线程类要执行的代码。③ 当要开启新...
  • java常见创建线程的三种方式

    千次阅读 2021-06-11 15:38:06
    方式1]继承Thread类创建线程 //使用方法1:继承Thread,重写其run()方法 new MyThread().start(); //使用方法2:创建匿名内部类Thread,重写其run()方法 new Thread() { @Override public void run() { ...
  • 看到这个标题的小伙伴先别着急喷我……在面试的时候,我们经常会被问到这种基础题:Java创建线程方式有几种? 比较正常的答法当然是三种: 继承Thread 实现Runnable接口 实现callable接口 一般来说这种属于送分...
  • Java 线程创建的四种方式

    千次阅读 2022-03-04 15:35:34
    Java 线程创建的四种方式 所有测试用例使用的是 jdk8 ,版本不同可能会有所不同,建议自己亲手试试。 Thread 方式 通过继承Thread类来创建新的线程(不推荐)。示例如下: 创建类 public class ThreadDemo extends ...
  • Java创建线程的五种方法

    千次阅读 2021-12-31 15:01:09
    Java创建线程的五种方法总结
  • java 创建线程的三种方式、创建线程池的四种方式

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

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

    千次阅读 2019-04-26 18:35:25
    java创建多线程有如下四种方式: 继承Thread类创建线程 实现Runnable接口创建线程 使用Callable和Future创建线程 使用线程池创建(使用java.util.concurrent.Executor接口) 下面分别介绍这四种创建多线程的方式...
  • 众所周知,我们在创建线程时有四种方法可以用,分别是: 1、继承Thread类创建线程 2、实现Runnable接口创建线程 3、使用Callable和Future创建线程 4、使用线程池创建(使用java.util.concurrent.Executor接口) 其中...
  • Java创建线程的两种方法

    千次阅读 2021-03-14 18:39:06
    摘要:其实两种方法归结起来看还是一种,都是利用Thread的构造器进行创建,区别就是一种是无参的,一种是有参的。一、继承Thread线程类:通过继承Thread类,重写run方法,子类对象就可以调用start方法启动线程,JVM...
  • Java 线程创建——8种方法

    千次阅读 2022-03-25 18:05:17
    1.使用Thread类创建 public class Thread6 { public static void main(String[] args) { //创建并初始化 Thread thread=new Thread(){ @Override public void run(){ Thread t=Thread.currentThread(); Sy
  • Java线程创建与运行

    千次阅读 2021-11-10 14:06:37
    进程是系统进行资源分配和调度的基本单位。而线程是程序运行的最小单位。...进入到Thread源码中可以看到源码提供了两种创建线程方式 方式一:继承Thread类 class PrimeThread extends Thread { long minP
  • java创建线程的三种方式及其对比

    万次阅读 多人点赞 2014-11-14 22:14:15
    Java创建线程主要有三种方式: 一、继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。 (2)创建Thread子类的实例...
  • Java线程01:创建新的执行线程

    千次阅读 2022-04-21 20:14:51
    在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程. main()称之为主线程,为系统的入口,用于执行整个程序 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作...
  • JAVA线程的三种创建方式

    万次阅读 多人点赞 2019-03-03 16:24:47
    一、概述 ...所以,我们创建线程时,主要是根据实际需求,编写放入线程执行体的代码。 二、三种创建方式 2.1第一种,通过继承Thread类创建线程类 通过继承Thread类来创建并启动多线程的步骤...
  • java有以下四种创建多线程的方式: 1:继承Thread类创建线程 2:实现Runnable接口创建线程 3:使用Callable和FutureTask创建线程 4:使用线程池,例如用Executor框架创建线程 DEMO代码: package thread; ...
  • java创建线程安全的Set集合

    千次阅读 2021-12-27 14:48:32
    java创建线程安全的Set集合的几种方法的对比:CopyOnWriteArraySet、Collections.synchronizedSet()、Collections.newSetFromMap(new ConcurrentHashMap())、ConcurrentHashMap.newKeySet()
  • Java1.5版本开始,就提供了 Callable 和 Future 来创建线程,这种方式也是在Java程序员面试中经常会被问到的问题。 上一小节介绍了Thread和Runnable两种方式创建线程,不过这两种方式创建线程都有一个缺陷:在执行...
  • 如何在java创建一个线程

    千次阅读 2021-03-04 09:01:44
    java中创建一个线程有两种方法:第一种:将类声明为...最后通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。首先我们创建线程的目的是为了开启一条执行路径,去...
  • java创建线程的两种方式及区别

    千次阅读 2018-07-24 18:35:47
    本文将介绍创建线程的两种方式,示例代码在下面,复制粘贴即可 继承Thread类方式和实现Runnable接口方式 区别:由于在开发的过程中,很多的类都会用到继承的方式,如果采用继承的方式会让各个类之间的关系变得错综...
  • java创建线程的四种方法

    千次阅读 2022-03-05 19:59:33
    第一种: 通过继承Thread类创建线程 第二种: 通过实现Runnable接口创建线程 这两种早已烂记于心,这里就不作过多的介绍, 主要介绍其源码 Thread类 implements Runnable thread空线程的run方法 是判断target是否...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,023,554
精华内容 409,421
关键字:

java创建线程的方式