Java线程实现的两种方式解析

 更新时间:2024年01月10日 10:09:31   作者:爱coding的同学  
这篇文章主要介绍了Java线程实现的两种方式解析,注意在构造器中启动这个线程的话,很容易造成this逃逸的问题,这是要注意的,这是通过直接集成thread来成为线程,同时在这种情况下,你可以通过调用合适的方法来,需要的朋友可以参考下

Java线程实现的两种方式解析

1.通过继承thread,得到一个任务类

/*注意在构造器中启动这个线程的话,很容易造成this逃逸的问题,这是要注意的
* 这是通过直接集成thread来成为线程。同时在这种情况下,你可以通过调用合适的方法来
* 给thread对象赋予具体的名称。*/
public class SimpleThread extends  Thread {
    private int countDown=5;
    private static int threadCount=0;
    public SimpleThread() {
        super(Integer.toString(++threadCount));//这是给这个thread赋予名字。
        start();
    }
    public String toString(){
        return "#"+getName()+"("+countDown+"), ";
    }
    public void run() {
        while (true) {
            System.out.print(this);
            if (--countDown == 0) {
                return;
            }
        }
    }
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new SimpleThread();
        }
    }
}

运行的结果为:

#1(5), 
#2(5), 
#3(5), 
#3(4), 
#3(3), 
#3(2), 
#4(5), 
#2(4), 
#5(5), 
#5(4), 
#1(4), 
#5(3), 
#5(2), 
#2(3), 
#2(2), 
#2(1), 
#4(4), 
#4(3), 
#4(2), 
#4(1), 
#3(1), 
#5(1), 
#1(3), 
#1(2), 
#1(1), 

2.通过实现Runnable接口,来得到一个任务类

//注意,Start()是在构造器中调用的。这个实例相当的简单,因此可能是安全的。但是应该注意到
//在构造器重启动线程可能会变得很有问题。因为另外一个任务可能会在构造器结束以前就开始执行了
//这意味着该任务能够访问处于不稳定状态的对象。这是优选Executor而不是显式地创建Thread对象的
//另外一个很重要的原因。
public class SelfManaged implements  Runnable {
    private int countDown=5;
    private Thread t = new Thread(this);
    public SelfManaged() {
        t.start();
    }
    public String toString(){
        return  Thread.currentThread().getName()+"("+countDown+")";
    }
    @Override
    public void run() {
        while (true) {
            System.out.println(this);
            if (--countDown == 0) {
                return;
            }
        }
    }
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new SelfManaged();
        }
    }
}

最后运行的结果为:

Thread-0(5)
Thread-2(5)
Thread-1(5)
Thread-1(4)
Thread-2(4)
Thread-2(3)
Thread-2(2)
Thread-2(1)
Thread-0(4)
Thread-0(3)
Thread-0(2)
Thread-0(1)
Thread-3(5)
Thread-1(3)
Thread-3(4)
Thread-4(5)
Thread-4(4)
Thread-4(3)
Thread-4(2)
Thread-4(1)
Thread-1(2)
Thread-1(1)
Thread-3(3)
Thread-3(2)
Thread-3(1)

3.为线程设置优先级

但是设置优先级只是一个建议。具体是否执行的话,还是要看系统内部的调度。

public class SimplePriorities implements  Runnable {
    private int countDown=5;
    private volatile  double d;
    private int priority;
    public SimplePriorities(int priority) {
        this.priority=priority;
    }
    public String toString(){
        return Thread.currentThread()+":"+countDown;
    }
    @Override
    public void run() {
        Thread.currentThread().setPriority(priority);//为这个线程设置优先级。
        while (true) {
            for (int i = 0; i < 10000; i++) {
                d += (Math.PI + Math.E)/(double)i;
                if (i / 1000 == 0) {
                    Thread.yield();
                }
            }
            System.out.println(this);
            if (--countDown == 0) {
                return;
            }
        }
    }
    public static void main(String[] args) {
        ExecutorService exec= Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
            exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
            exec.shutdown();
        }
    }
}

4.继承thread和实现runnable之间的区别

1、如是是实现了Runnable接口的话,那么就为实现多继承提供了方便。因为java中,只允许单继承。

2、实现runnable接口可以实现资源的共享。

这就是它们之间的最大的区别。

下面以一个买票的例子来说明它们之间的区别。

class MyThread extends Thread{  
    private int ticket=10;  
    public void run(){  
        for(int i=0;i<20;i++){  
            if(this.ticket>0){  
                System.out.println("卖票:ticket"+this.ticket--);  
            }  
        }  
    }  
}; 

下面通过三个线程对象,同时卖票:

package org.demo.dff;  
    public class ThreadTicket {  
    public static void main(String[] args) {  
        MyThread mt1=new MyThread();  
        MyThread mt2=new MyThread();  
        MyThread mt3=new MyThread();  
        mt1.start();//每个线程都各卖了10张,共卖了30张票  
        mt2.start();//但实际只有10张票,每个线程都卖自己的票  
        mt3.start();//没有达到资源共享  
        }  
    } 
 package org.demo.runnable;  
 class MyThread implements Runnable{  
    private int ticket=10;  
    public void run(){  
        for(int i=0;i<20;i++){  
            if(this.ticket>0){  
            System.out.println("卖票:ticket"+this.ticket--);  
                 }  
         }  
    }  
 }  
 package org.demo.runnable;  
 public class RunnableTicket {  
    public static void main(String[] args) {  
        MyThread mt=new MyThread();  
         new Thread(mt).start();//同一个mt,但是在Thread中就不可以,如果用同一  
         new Thread(mt).start();//个实例化对象mt,就会出现异常  
         new Thread(mt).start();  
        }  
    }; 

到此这篇关于Java线程实现的两种方式解析的文章就介绍到这了,更多相关Java线程实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springcloud之自定义简易消费服务组件

    springcloud之自定义简易消费服务组件

    这篇文章主要介绍了springcloud之自定义简易消费服务组件,本篇来使用rest+ribbon消费服务,并且通过轮询方式来自定义了个简易消费组件,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • 解决SpringMvc中普通类注入Service为null的问题

    解决SpringMvc中普通类注入Service为null的问题

    这篇文章主要介绍了解决SpringMvc中普通类注入Service为null的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Spring Boot 配置随机数的技巧代码详解

    Spring Boot 配置随机数的技巧代码详解

    这篇文章主要介绍了Spring Boot 配置随机数技巧,spring boot 支持在系统加载的时候配置随机数,具体实例代码大家参考下本文
    2018-05-05
  • Java的反射机制---动态调用对象的简单方法

    Java的反射机制---动态调用对象的简单方法

    下面小编就为大家带来一篇Java的反射机制---动态调用对象的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • Java中的CompletableFuture原理与用法

    Java中的CompletableFuture原理与用法

    CompletableFuture 是由Java8引入的,这让我们编写清晰可读的异步代码变得更加容易,该类功能比Future 更加强大,在Java中CompletableFuture用于异步编程,异步通常意味着非阻塞,运行任务单独的线程,与主线程隔离,这篇文章介绍CompletableFuture原理与用法,一起看看吧
    2024-01-01
  • Spring-Security实现登录接口流程

    Spring-Security实现登录接口流程

    Security 是 Spring 家族中的一个安全管理框架,SpringSecurity的原理其实就是一个过滤器链,内部包含了提供各种功能的过滤器,这篇文章主要介绍了Spring-Security实现登录接口,需要的朋友可以参考下
    2023-05-05
  • Java实现四则混合运算代码示例

    Java实现四则混合运算代码示例

    这篇文章主要介绍了Java实现四则混合运算代码示例,文中展示了详细代码,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • 使用java.nio.file 库优雅的操作文件详解

    使用java.nio.file 库优雅的操作文件详解

    这篇文章主要介绍了使用java.nio.file 库优雅的操作文件详解,需要的朋友可以参考下
    2023-05-05
  • Java中Stream流中map和forEach的区别详解

    Java中Stream流中map和forEach的区别详解

    本文主要介绍了Java中Stream流中map和forEach的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • Java枚举类使用场景及实例解析

    Java枚举类使用场景及实例解析

    这篇文章主要介绍了Java枚举类使用场景及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04

最新评论