javaSE (三十五)多线程 ( 多线程实现方法和区别、同步代码块和方法(线程安全))

主要还是熟悉api,熟悉方法,简单,需要多实践


1、 多线程实现方法和区别:

  1. 多线程实现的两种方法:
    1)类继承Thread类或实现Runnable接口,重写run()方法
    2)创建Thread的子类对象(需要开几个线程就创建几个对象,可创建匿名内部类)
    3)子类对象.start()或者将实现了Runnable接口的对象当作参数放到Thread构造方法里再子类对象.start()
    也可以采用匿名类的方法重写Thread里面的run()方法,将我们要执行的语句写到run()方法里面,然后直接.start()

多线程的要执行的代码主要就是写在重写的run方法里,子类如果重写了run,那就调用子类的run,如下,如果采用匿名类,因为编译看父类,运行看子类,如果子类没有重写run,那就直接用父类重写过的run

Thread的run源码,如果子类不为空,就调用子类的run:

 public void run() {
        if (target != null) {
            target.run();
        }
    }

继承Thread类如果需要在几个线程里面共享的数据,比如,1000张票,四个窗口卖,这个票需要变成静态的,就是在类加载的同时加载进方法区的静态区,由线程所共享,但是实现Runnable接口就不需要了,因为只创建了一个类,然后用thread的构造方法创建四个线程一起运行这个类
2. 两种方法源码的区别:
1)继承Thread:由于子类重写了Thread的run(),当调用start()的时候,直接找子类的run()方法
2)实现Runnable:构造函数中传入了Runnable的引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空的时候编译看的是Runnable的run(),运行时执行的是子类的run()方法
3. 写代码时的区别
1) 继承Thread:好处是可以直接使用Thread类中的方法,代码简单,弊端是如果已经有了父类,就不能用这种方法(Java中每个类都只能继承一个类,但可以实现多个接口
2)实现Runnable:好处是即使自己定义的线程类有了父类也没关系,可以实现多个接口;弊端是不能直接使用Thread中的方法需要

2、同步代码块和方法:
将代码块或者方法用锁对象锁起来,这样在完整低执行了一次代码块或者方法后CPU才会切换线程(也就是说,线程之间不干扰,是线程安全的)
synchronized(锁对象){方法}: 同步代码块,锁机制,锁对象可以是任意的,但是锁只能是相同的类(匿名类就不行),如果用引用数据类型变量(比如自己创建的对象)当作锁对象,必须是静态的,static
synchronized 方法(){}: 非静态同步方法,直接用关键字修饰方法,其锁对象是this
static synchronized 方法(){}: 静态同步方法,直接用关键字修饰方法,其锁对象是字节码对象(就像是创建了同步代码块然后把锁对象当作参数放到小括号里)

注意:嵌套同步代码块会造成死锁,最好不要嵌套

猜你喜欢

转载自blog.csdn.net/weixin_39782583/article/details/84962366