ASP.Net+Android+IOS开发、.Net培训、期待与您交流!
线程的生命周期
昨天我们认识了什么是线程和实现他的两种方式,今天我们再进一步了解。线程的状态转换是线程控制的基础。线程状态总的可分为五大状态:分别是生、死、可运行、运行、等待/阻塞。如下图:
上图能够清晰的看出线程见得状态是如何转换的,并且标注了在不同的状态线程对cpu的资源使用情况。(其中对线程操作的方法,读者可去查阅JDK API文档。)
线程的同步锁
有两种方式:第一种是利用synchronized同步代码块,格式为
其中对象为锁对象,一个线程在持有锁标记时才能进入同步代码区,在执行完后,释放该锁标记;第二种是利用了synchronized的同步函数,格式为: 如:
它对访问当前的对象(this)加锁, 哪个线程能拿到该对象(临界资源)的锁,哪个线程就能调用该对象(临界资源)的同步方法。
synchronized(对象){ //代码}
其中对象为锁对象,一个线程在持有锁标记时才能进入同步代码区,在执行完后,释放该锁标记;第二种是利用了synchronized的同步函数,格式为: 如:
public synchronized void run(){}
它对访问当前的对象(this)加锁, 哪个线程能拿到该对象(临界资源)的锁,哪个线程就能调用该对象(临界资源)的同步方法。
比如下面的简单售票系统:
/*
* 问题描述:有一百张票,有四个售票点在同时售票,售完为止
* 利用了synchronized同步代码块去解决同步问题
*/
public class Demo_3 {
public static void main(String[] args) {
Tickets tick = new Tickets();
// 创建四个线程
Thread t1 = new Thread(tick);
Thread t2 = new Thread(tick);
Thread t3 = new Thread(tick);
Thread t4 = new Thread(tick);
// 启动线程
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Tickets implements Runnable {
private int count = 100;
Object obj = new Object();
@Override
public void run() {
synchronized (obj) {
while (true) {
if (count > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "..."
+ count--);
}
}
}
}
}