`
十三月的
  • 浏览: 165155 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

线程同步,原来你很有意思

阅读更多

 

     看了篇文章,关于线程同步的,觉得很符合自己的逻辑思考方式,于是总结下自己的思路。(主要以问题为导向)

1:多线程的引入,解决了什么?

     首先是了解同步I/O操作和异步I/O操作的区别。同步操纵是指在执行I/O操作的时候,方法会一直处于等待的状态中,直到I/O操作完成;异步操作是指一旦I/O操作开始执行,程序就可以转向其他地方执行其他操作。

     显然异步的出现,可以很好的利用CPU资源。对于在同一时刻操作系统可能需要面对多个I/O操作的问题,如果是同步操作的话,该时刻只能有一个线程执行,其他的都会处于等待状态,而采用多线程的话,刚好就解决了上述的问题。显然多线程并不是为了提高程序运行的效率,而是通过提高系统的资源的利用率提高了系统的效率。                                                          

2:除了解决问题还带来了什么问题或者说需要注意什么?

     当多个线程操作的对象是分别独立的话,毫无疑问没什么问题,但是一旦线程之间操作的对象有相同的,就需要注意了。这也就是线程的同步问题。此处的同步是指协同,互相配合的意思。比如当前正在执行了线程A,但是此时需要线程B的数据,于是线程A停下来,让B先执行,然后A在执行。

       线程同步问题有2个特征:1,共享资源;2,资源是可变的。共享不必说,如果两个线程本身就独立运行,没有共享的数据,就根本不会有什么冲突。资源可变是指,共享的资源如果是不变的,那么同步也就没什么必要了。

3:那么如何对待同步问题?

    最简单的方式就是将共享的资源加上一把锁。这把锁只有一把钥匙,各个线程需要竞争这把钥匙,只有得到了这把钥匙才能对数据进行操作,其他的线程会等待。

4:那么这把锁应该加在什么地方呢?

      按照正常的思维来讲这把所必然是属于共享文件的,理论上来讲是这样的。对于比较完善的文件系统,数据库系统来讲,他们都有自己的锁机制。然而我们平时操作的大部分都是比较简单的对象,对于这些对象怎么加锁呢?

5:对于比较简单的对象,锁应该加在那里呢?

       理论上一个可行的办法是,在每一个对象内部开辟一块内存空间准们存放这个锁,但是面临的实际问题是对于线程同步问题并不是非常普遍,如果为了解决这种概率较小的问题,此方案显然得不偿失。于是有了现在常用的办法,将同步锁加在了程序中的代码块上。

6:那么这把锁到底应该是什么样子的呢?

     java中,其实任何一个对象都可以充当。比如Synchronized(new Dog()),

这里的新建的Dog,就可以充当这样的一把锁。

7:难道就真的随便写一个对象就真的实现了同步锁吗?

     其实不是,对于对象锁还有另外的一个要求,就是对于同步线程操作共享资源的代码块中必须是同一把对象锁,就是说对象锁对各个线程来讲也是共享的。实现共享的话,可以声明一个static的成员变量类型的对象,也可以声明称final类型的,不可改变。

8:实现了同步锁,那么同步锁放在代码块中的什么位置呢?

     很简单的方式就是放在了定义的函数体上。

9:直接放在函数体上是合适的吗?

    其实是不一定合适的。原因如下:当多个线程争取同一个对象锁的时候,这些线程会有两种状态,一种是在就绪队列中,一种是在待召队列中。就好像是去医院看病,在医师的办公室里总是有几个人,在门外变有另外一个队伍。里面的是就绪队列,外面的是待召队列。每次某个线程释放对象锁的时候,处在就绪队列里的线程就会重新争夺对象锁。而处在待召队列里的线程得到某种信号后会移到就绪队列中去。所以想要实现线程的同步实际上是很耗费资源的一种操作,应该尽量缩小线程同步的范围。可以将同步关键字加在方法中的某一部分。

       写完后发现线程还是很有意思的......

          

 

 

1
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics