Java笔记-并发

  1. 站在程序性能的角度看,在单处理器的机器上使用并发不会有对改善性能有什么影响,除非一个任务可能阻塞。
  2. volatile(易变性)longdouble是分开的两个32位操作,所以是非原子性的,可能会出现在操作一部分后系统出现上下文切换,造成读写数据错误。使用volatile定义longdouble,保证其原子性。(64位系统中longdouble也是非原子性的,详见java虚语言规范)
  3. volatile关键字确保属性在整个应用中的可见性。如果声明一个属性为volatile,则一旦对这个属性进行写入操作,所有的读取都能立即发现它的变化。即使涉及到处理器缓存时,它也是正确的-volatile修饰的属性会立即写入内存中(不放在处理机缓存中),而读取是从内存中获取。
  4. It’s important to understand that atomicity and volatility are distinct concepts. An atomic operation on a non-volatile field will not necessarily be flushed to main memory, and so another task that reads that field will not necessarily see the new value. If multiple tasks are accessing a field, that field should be volatile; otherwise, the field should only be accessed via synchronization. Synchronization also causes flushing to main memory, so if a field is completely guarded by synchronized methods or blocks, it is not necessary to make it volatile.(读着就觉得牛逼)Anywrites that a task makes will be visible to that task, so you don’t need tomake a field volatile if it is only seen within a task.

   volatile doesn’t work when the value of a field depends on its previous value (such asincrementing a counter), nor does it work on fields whose            values areconstrained by the values of other fields, such as the lower and upper bound ofa Range class which must obey the constraint lower                <= upper.

 

  1.  线程状态:

    1 New:当线程创建时,线程在这个状态停留片刻时间。它开辟所需要的所有系统资源和进行初始化。在这个时刻,这个线程有资格去获取CPU时间。接下来调度器会将这个线程转换到可运行状态或阻塞状态。

    2.Runnable:这意味着当此线程获取到CPU分片机制所提供的CPU执行周期时,可以运行。所以此线程在任何时刻可能运行也可能不运行,但是当时间调度机制安排它运行时,没有其他地方阻挡它运行。它没有处于死亡或者阻塞状态。

    3Blocked:线程可以运行,但是某些地方阻挡了其运行。当一个线程处于阻塞状态,线程调度器会直接跳过它,并且不会给它CPU时间。如果没有再次进入可运行状态,它不会进行任何其他操作。

    4.Dead:当一个线程处于死亡或者终结状态时,它将不会再被调度执行,也将不再会获取CPU时间。它的任务结束了,也不会再次运行了。一个任务死亡的一种方式是从run()方法中返回,但是一个任务线程也可以被中断。

 

  1.  造成阻塞的几种情况:

    1通过调用sleep(milliseconds)方法使任务进入睡眠状态,在这种状况下,在指定的时间内,它不会运行。

    2.)通过wait()方法挂起了线程的执行。当这个线程收到notify()或者notifyAll()信息(or the equivalent signal( ) or signalAll( ) for theJava SE5 java.util.concurrent library tools),它将再次可以运行。

    3.)任务在等待I/O完成。

    4任务在尝试调用另一个对象上的synchronized方法,而由于那个对象的锁已被其他任务获取到,这个任务不能获取那个对象上的锁。

 

  1.  Java线程中,异常用来做终止线程。

    1sleep(milliseconds)造成的阻塞可通过interrupt()方法中断,I/O阻塞和synchronized造成的阻塞不可以通过interrupt()中断。

    2.)可以通过关闭造成任务阻塞的资源(io流等)来终止线程。

    3.)由ReentrantLocks造成阻塞的任务可以通过interrupt()方法中断。

  1. Sleep()yield()都不释放锁,wait()释放锁。
  2. wait( ), notify( )notifyAll( )方法会操作锁(sleep()不操作锁)。这三个方法只能在同步方法或者同步代码块中调用(在非同步方法和同步代码块中运行时会抛出异常),而sleep()可以在非同步方法和代码块中调用。
  3. java.util.concurrent.BlockingQueue:同步队列,一次只允许一个任务从队列中获取元素或者向队列中插入元素。

当队列是空的,而一个任务尝试去获取队列中的元素时,这个任务将被挂起;当有元素可以访问时挂起的任务再继续执行。

相比于wait()notifyAll(),同步队列更加简洁和可靠。

  1. 同时满足以下四个条件则可能发生死锁:

1)互相排斥。至少一个资源是所有任务不共享的。

2)至少一个任务已经持有一个资源,并且等待获取正在被另一个任务所持有的资源。

3)一个资源不能提前从一个任务中拿走。多个任务只能以正常的事件方式释放资源。

4)循环等待。

  1. DelayQueueis an unbounded BlockingQueue of objects that implement the Delayed interface.继承了同步队列,用来放实现了Delaye接口的元素 。放置的所有元素按照延迟时间排序,延迟时间短的元素先执行。
  2. PriorityBlockingQueueis basically a priority queue that has blocking retrieval operations.是一个有同步访问操作的优先级队列。队列中元素实现Comparable接口,用来比较优先级。

你可能感兴趣的:(Java)