线程2
计算机通常只有一个CPU,在任意时刻只能执行一条机器指令,每个线程只有获得CPU的使用权才能执行指令。线程调度是指按照特定机制为多个线程分配CPU的使用权.
分类:分时调度模型和抢占式调度模型
分时调度模型是指让所有的线程轮流获得cpu的使用权,并且平均分配每个线程占用的CPU的时间片这个也比较好理解。
java虚拟机采用抢占式调度模型,是指优先让可运行池中优先级高的线程占用CPU,如果可运行池中的线程优先级相同,那么就随机选择一个线程,使其占用CPU。处于运行状态的线程会一直运行,直至它不得不放弃CPU。
线程的调度不是跨平台的,它 不仅仅取决于java虚拟机,还依赖于操作系统。在某些操作系统中,只要运行中的线程没有遇到阻塞,就不会放弃CPU;在某些操作系统中,即使线程没有遇到阻塞,也会运行一段时间后放弃CPU,给其它线程运行的机会。 例如在windows下,每个线程就是在一定的时间片内需要让出CPU.所以即使优先级别低得线程也不至于被饿死。
2.线程优先级
通俗的理解是,优先级别高的线程获得的时间片更长。线程优先级根据操作系统的不同,分级不同。java中优先级共有10级,1级最低(MIN-PRIORITY)。10级最高(MAX_PRIORITY
)。默认为NORM_PRIORITY
(5级)。一般线程为默认优先级,包括main线程。
3.
(1)在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。当调用sleep ()函数后,线程不会释放它的“锁标志”。 (2)当sleep的时间过后,并不意味着当前线程马上会继续运行,而只是意味着该线程现在的状态由阻塞变为runnable。具体什么时间开始运行需要JVM来决定。 (3)需要捕获InterruptedException (4)sleep(0)的含义是让JVM从等待线程的队列里重新选择一个线程,也许是自己,也许是别的线程。该用法同yield()等同。 |
4.threadobject.join() 使调用join()的线程执行完毕后才能执行其它线程,在一定意义上,它可以实现同步的功能。
例如
5.threadobject.yield()
1) 通过yield ()函数,可使线程进入可执行状态,排程器从可执行状态的线程中重新进行排程。所以调用了yield()的函数也有可能马上被执行。
2) 当调用yield ()函数后,线程不会释放它的“锁标志”。
6.synchronized
synchronized有两种用法,一个是synchronized method。一个是synchronized block。是表示对临界资源进行对象锁。以进行排他性的访问。每个对象都有一个对象锁,每个类有一个类锁。
用法一:锁定的是调用这个同步方法对象
Public synchronized void methodAAA()
{
//….
}
用法二:this指的就是调用这个方法的对象
public void methodAAA()
{
synchronized (this) // (1)
{
//…..
}
}
用法三:同用法二类似,获得的是obj这把锁。一般object可以随便定义,例如private byte lock = new byte[0]; // 特殊的instance变量。因为获得一个锁后才能操作synchronized代码块中的代码。
public void methodAAA()
{
Object obj = new Object ();
synchronized (obj ) // (1)
{
//…..
}
}
用法四:类锁。假设foo是Foo的对象。不能使用synchronized(foo.getClass).可以用Foo.classClass Foo
{
public synchronized static void methodAAA() // 同步的static 函数
{
//….
}
}注:
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
四、当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
五、以上规则对其它对象锁同样适用.
7.wait() notify() notifyAll()
(1)三个都是Ojbect的函数,调用wait时会使运行该object的线程阻塞。同时释放对象锁,使线程所在对象中的其它synchronized数据可被别的线程使用。
(2)当对一个对象执行notify()时,会从线程等待池中移走该任意一个线程,并把它放到锁标志等待池中;当对一个对象执行notifyAll()时,会从线程等待池中移走所有该对象的所有线程,并把它们放到锁标志等待池中
(3)三个函数都必须要在synchronized中调用,否则会在运行时IllegalMonitorStateException。
8.suspend()、resume()
可能造成死锁,已过时。