美文网首页
Java线程学习笔记(2)

Java线程学习笔记(2)

作者: 哦呵呵_3579 | 来源:发表于2018-04-19 23:44 被阅读0次

上次写到Thread这个类,以及线程是如何跑起来的,其实这个类里面还有一些值得探究的地方。
1.Thread类定义了线程的状态。Thread类中定义了一个枚举,

public enum State {
        NEW,
        RUNNABLE,
        BLOCKED,
        WAITING,
        TIMED_WAITING,
        TERMINATED;
    }

这个枚举定义了线程所有的运行状态,可以发现跟网上的一些文章并不相同,感觉网上更多的是对线程状态的总结吧,而这个枚举中列出的则是更实际的运行状态,其中RUNNABLE状态代表运行或者等待系统线程调用的状态,等待状态分成了不会超时的等待与会超时的等待两种,但总觉的网上的那些总结更好理解。
2.synchronized和volatile关键字。
多线程就意味着存在对一个变量的并发操作,比如一个int值a,初始状态是0,1号线程获取a的值时为0,并且把a+1,还没来得及累加的时候2号线程也获取a的值,并且把a+1,结果就是最后a等于1而非等于2。为了让a等于2我们就需要用一些手段了。
synchronized关键字:用在修饰方法或者代码块
volatile关键字:用在修饰变量

class Plus {
    @Volatile var  a = 0
    fun plus()
    {
        synchronized(this){
            a+=1
        }
    }
    @Synchronized fun plus1(){
        a+=1
    }
}

synchronized关键字是在JVM层面实现了对临界资源的同步互斥访问,通过对对象的头文件来操作,从而达到加锁和释放锁的目的,让同一时间只有一个线程可以访问该方法或者代码块,其他想访问的线程都处于BLOCKED状态,直到前面一个线程从该方法或者代码块中退出,后面的线程才能访问,这保证了原子性,可以让a安全的变成2。
volatile关键字其实并不能保证a的原子性,volatile关键字只是保证了a的可见性,比如当1号线程获取到a的值并且进行修改的时候,如果2号线程刚获取到a的值为0,当1号线程修改完毕后2号线程中获取到的a的值会变成1,这时候2号线程再累加就变成了2。但如果是完全同时进行则a还是1。
https://www.cnblogs.com/hapjin/p/5492880.html这篇文章写得还是比较详细的,有兴趣的可以研究一下。
3.yield方法,这个方法的描述中写着该线程愿意让出资源来给其他priority更高的线程。因为cpu的线程是有限的,所以这个方法相当于是让处理器有限处理比较紧急的线程,紧急度不高的暂缓处理,通过这样的方式提高单处理器的处理能力,类似于Kotlin的协程。
Thread类虽然使用方便,但是有一些蛋疼的地方
1.线程不可控,起的是系统默认的线程。
2.Runnable接口没有返回值,只是纯粹的气了一个线程去把run方法里面的代码执行一遍。
由此引申出来另外两个接口:Executor和Future。
由于本人能力有限,有些地方可能描述不正确,欢迎大家指正,谢谢。

相关文章

网友评论

      本文标题:Java线程学习笔记(2)

      本文链接:https://www.haomeiwen.com/subject/hawgkftx.html