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线程实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot集成slf4j+log4j2的示例代码

    SpringBoot集成slf4j+log4j2的示例代码

    这篇文章主要介绍了SpringBoot集成slf4j+log4j2的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • 使用Java提取PDF中的文字的三种常见方法

    使用Java提取PDF中的文字的三种常见方法

    这篇文章主要介绍了Java中提取PDF文本的三种方法:ApachePDFBox(普通PDF,轻量易用)、iText(复杂格式,功能强大)、TesseractOCR(扫描版,需OCR识别),并给出各场景下的推荐选择,需要的朋友可以参考下
    2025-06-06
  • java 实现多线程的方法总结

    java 实现多线程的方法总结

    这篇文章主要介绍了java 实现多线程的方法总结的相关资料,需要的朋友可以参考下
    2016-10-10
  • 深入浅析SPI机制在JDK与Spring Boot中的应用

    深入浅析SPI机制在JDK与Spring Boot中的应用

    SPI是一种使软件框架或库更加模块化、可扩展和可维护的有效方法。通过遵循“开闭原则”, SPI 确保了系统的稳定性和灵活性,从而满足了不断变化的业务需求,这篇文章主要介绍了SPI机制在JDK与Spring Boot中的应用,需要的朋友可以参考下
    2023-09-09
  • 10个Elasticsearch查询的实用技巧分享

    10个Elasticsearch查询的实用技巧分享

    Elasticsearch是一个非常流行的搜索引擎,已经成为了许多企业的首选解决方案。本文将向大家介绍10个实用的Elasticsearch查询技巧,并配上对应的代码示例,希望对大家有所帮助
    2023-04-04
  • 解决IDEA中同项目引用报红问题

    解决IDEA中同项目引用报红问题

    在IDEA中,如果项目引用报红,可能是因为IDEA的引用缓存问题,可以通过File->Invalidate Caches/Restart清空缓存并重建索引来解决,这个方法可以帮助解决同项目中引用找不到的问题,恢复正常的项目引用,消除报红
    2024-09-09
  • idea中引入了gb2312编码的文件的解决方法

    idea中引入了gb2312编码的文件的解决方法

    这篇文章主要介绍了idea中引入了gb2312编码的文件的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java在枚举类型中增加自定义方法详解

    Java在枚举类型中增加自定义方法详解

    这篇文章主要介绍了Java在枚举类型中增加自定义方法详解,对于枚举类型来说,除了无法继承它以外,基本可以将它看作一个普通的类,这意味着你可以在里面增加自定义的方法,甚至可以增加一个 main() 方法,需要的朋友可以参考下
    2023-11-11
  • MyBatis SqlSource源码示例解析

    MyBatis SqlSource源码示例解析

    这篇文章主要为大家介绍了MyBatis SqlSource源码示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • SpringBoot基于拦截器与ThreadLocal实现用户登录校验

    SpringBoot基于拦截器与ThreadLocal实现用户登录校验

    本文介绍了一种在SpringBoot中实现统一登录校验和上下文共享的解决方案,通过使用拦截器、ThreadLocal和自定义工具类,实现了在请求处理过程中优雅地获取当前登录用户信息,并且避免了在每个Controller方法中重复编写校验代码,需要的朋友可以参考下
    2025-12-12

最新评论