多线程一些基础实现

发布时间:2020-05-19 08:23:55 作者:SerryYang
来源:网络 阅读:249

继承Thread类方式

1. 线程启动时:一定是调用Thread类的start()方法,因为通过源码解析发现,start()方法中,最后会调用以native关键字修饰的start0()方法,该方法会通过JVM实现不同操作系统不同实现的

   资源调度分配;

2.  Native关键字:调用本机的操作系统函数。


实现Runnable接口方式

1. 实现Runnable接口:由于继承Thread类会造成单继承的局限性,所以利用接口来实现;

2. Runnable接口:因为其是函数式接口,所以该接口中只有一个方法,可以使用Lamda表达式完成;

3. @FunctionalInterface:修饰的接口为函数式接口;

4. 由于启动发多线程只能通过start()方法,但Runnable方法中没有此方法,故实现该接口并启动一个线程,是通过Thread的构造函数发现:

   public Thread(Runnable targer) ,所以可以通过此方式来启动一个多线程;


实例:Runnnable接口方式

public class Test11 {

    public static void main(String[] args) {
        Test11Demo t1 = new Test11Demo("线程1");
        Test11Demo t2 = new Test11Demo("线程2");
        Test11Demo t3 = new Test11Demo("线程3");
        new Thread(t1).start();
        new Thread(t2).start();
        new Thread(t3).start();
    }

}

class Test11Demo implements Runnable {
    
    private String name;
    
    Test11Demo(String name) {
        this.name = name;
    }
    
    @Override
    public void run() {
        for (int x = 0; x < 10; x++) {
            System.out.println(this.name + ",x=" + x);
        }
    }
    
}


实例:Lamda方式,内部类方式

在原来代码基础上,添加测试代码

public static void main(String[] args) throws Exception {
    Test11Demo t1 = new Test11Demo("线程1");
    Test11Demo t2 = new Test11Demo("线程2");
    Test11Demo t3 = new Test11Demo("线程3");
    new Thread(t1).start();
    new Thread(t2).start();
    new Thread(t3).start();

    final String name1 = "Lamda测试";
    new Thread( ()->{
        for (int x = 0; x < 10; x++) {
            System.out.println(name1 + ",x=" + x);
        }
    }).start();


    final String name = "内部类测试";
    new Thread(new Runnable() {
        @Override
        public void run() {
            for (int x = 0; x < 10; x++) {
                System.out.println(name + ",x=" + x);
            }
        }
    }).start();
}


两种方式,启动线程的异同

1. 查看源码可知,Thread类定义:

   public classThread extends Object implements Runnable

2. 类关系图:

多线程一些基础实现


综上,可知,

多线程需要一个线程主类:可以继承Thread类,也可以实现Runnable接口;

使用Runnable接口,可以更好的实现数据共享的操作;并可以避免Thread类带来的单继承局限性;



线程的命名和取得

1. 线程的所有操作方法基本上都已经在Thread类中定义完整;

2. 如下方法,可提供线程名称操作:

① 构造方法:public Thread(Runnable target,String name)

② 设置名字:public final void setName(String name)

③ 获取名字:public final String getName()

④ 由于线程执行本身不确定状态,

提供方法:public static Thread currentThread()来取得当前线程

3. 如果在设置线程对象名称时,没有设置具体名字,则会采用默认名字进行定义;

4. 每一个JVM至少会启动两个线程:主线程,GC线程;


线程的休眠

休眠方法:sleep();线程的睡眠,是有先后顺序的


线程的优先级

1. 优先级操作方法:

设置优先级:public final void setPriority(int newPriority);

取得优先级:public final int getPriority();

2. 优先级相关常量:

   最高优先级:public final static int MAX_PRIORITY = 10;

   中等优先级:public final static int NORM_PRIORITY = 5;

   最低优先级:public final static int MIN_PRIORITY = 1;

3.  理论上,会根据设置的优先级进行线程的启动运行;

   主线程,属于一般优先级。


线程的同步与死锁

1. 同步问题的引出:多个线程需要访问统一资源;

2. 同步代码块执行效率要低于异步,同步代码块使用:synchronized关键字

3. 异步执行效率高,但数据不准确;同步代码执行效率慢,但会保证数据的有效性,同时线程安全。

4. 死锁:(了解) 如果程序中出现过多同步,将会产生死锁问题;





---下一篇,线程中的生产者与消费者理解--线程的应用场景之一







推荐阅读:
  1. 一些关于MySQL事务的基础知识
  2. 多线程基础

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java 基础实现

上一篇:CountDownLatch了解

下一篇:android广播指定权限

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》