多线程3:Java内置锁与synchronized关键字
来源:互联网 发布:话语分析知乎 编辑:程序博客网 时间:2024/05/16 06:28
Java提供了一种内置的锁机制来支持原子性
每一个Java对象都可以用作一个实现同步的锁,称为内置锁,线程进入同步代码块之前自动获取到锁,代码块执行完成正常退出或代码块中抛出异常退出时会释放掉锁
内置锁为互斥锁,即线程A获取到锁后,线程B阻塞直到线程A释放锁,线程B才能获取到同一个锁
内置锁使用synchronized关键字实现,synchronized关键字有两种用法:
1,修饰需要进行同步的方法(所有访问状态变量的方法都必须进行同步),此时充当锁的对象为调用同步方法的对象
public class Test{private int count = 0;public synchronized int add(){count += 1;return count;}public synchronized int delete(){count -= 1;return count;}}
2,同步代码块
和直接使用synchronized修饰需要同步的方法是一样的,但是锁的粒度可以更细,并且充当锁的对象不一定是this,也可以是其它对象,所以使用起来更加灵活
public class Test{private int count = 0;public int add(){synchronized(this){count += 1;}return count;}public int delete(){synchronized(this){count -= 1;}return count;}}
用synchronized关键字修饰的方法可以认为是一个横跨整个方法体的同步代码块
public class Status {private int num = 0;public void selfIncrease(){num = num + 1;System.out.println(Thread.currentThread().getName() + "|" + num);}}
public class Task implements Runnable {private Status status;public Task(Status status){this.status = status;}public void run() {synchronized (status) {status.selfIncrease();}}public static void main(String[] args) {Status status = new Status();Task task = new Task(status);Thread t1 = new Thread(task);Thread t2 = new Thread(task);Thread t3 = new Thread(task);Thread t4 = new Thread(task);t1.start();t2.start();t3.start();t4.start();}}
运行结果为:
Thread-0|1Thread-3|2Thread-2|3Thread-1|4
修改上面的代码,每个线程运行时创建一个新的Status对象,而不是像上面的代码,4个线程共用同一个Status对象:
public class Task implements Runnable {public void run() {Status status = new Status();synchronized (status) {status.selfIncrease();}}public static void main(String[] args) {Task task = new Task();Thread t1 = new Thread(task);Thread t2 = new Thread(task);Thread t3 = new Thread(task);Thread t4 = new Thread(task);t1.start();t2.start();t3.start();t4.start();}}
由于充当锁的对象实例不一定是同一个对象(hashcode不同),同步失效:
Thread-0|1Thread-1|1Thread-3|1Thread-2|1
因此同步代码块中充当锁的对象必须为同一个对象
public class Task implements Runnable {private Status status;public Task(Status status){this.status = status;}public void run() {synchronized (status) {System.out.println("Thread lock");System.out.println("Thread:" + status.getNum());System.out.println("Thread over");}}public static void main(String[] args) {Status status = new Status();Task task = new Task(status);Thread t = new Thread(task);t.start();//synchronized(status){System.out.println("Main");status.setNum(1);System.out.println("Main:" + status.getNum());//}}}
运行结果为:
MainThread lockMain:1Thread:1Thread over
从运行结果可以看出,在Thread线程锁定status对象的时候,Main线程在Thread线程释放锁对象前依然能够修改status对象的num域,说明锁没有生效
Main线程中没有对status对象进行同步,故在Thread线程锁定status对象的时候不需要阻塞,可以直接操作status对象,因此所有使用同步对象的地方都必须进行同步
修改方式为:Task类的main方法中,在操作status对象时进行同步(去掉代码中的注释部分)
如果锁对象为静态变量,或使用synchronized关键字修饰静态方法,则锁对象为Class对象
public class Status {private static int num = 0;public synchronized static void selfIncrease(){num = num + 1;System.out.println(Thread.currentThread().getName() + "|" + num);}}
public class Task implements Runnable {public void run() {Status.selfIncrease();}public static void main(String[] args) throws Exception {Task task = new Task();Thread t1 = new Thread(task);Thread t2 = new Thread(task);Thread t3 = new Thread(task);Thread t4 = new Thread(task);t1.start();t2.start();t3.start();t4.start();}}
运行结果如下:
Thread-0|1Thread-1|2Thread-3|3Thread-2|4
相当于:
public class Status {private static int num = 0;public static void selfIncrease(){synchronized(Status.class){num = num + 1;System.out.println(Thread.currentThread().getName() + "|" + num);}}}
或是:
public class Status {private static int num = 0;private static Object lock = new Object();public static void selfIncrease(){synchronized(lock){num = num + 1;System.out.println(Thread.currentThread().getName() + "|" + num);}}}
- 多线程:Java内置锁与synchronized关键字
- 多线程3:Java内置锁与synchronized关键字
- Java内置锁与synchronized关键字
- Java多线程(3)——同步与synchronized关键字
- Java多线程:线程同步与关键字synchronized
- Java synchronized关键字与多线程并发访问
- 多线程与synchronized关键字
- Java多线程 synchronized关键字
- Java多线程-synchronized关键字
- Java 多线程 Synchronized关键字
- Java多线程-synchronized关键字
- 【java多线程 关键字】synchronized
- Java多线程同步 synchronized关键字
- java多线程关键字synchronized用法
- Java 多线程----synchronized关键字详解
- Java 多线程 synchronized关键字详解
- Java 多线程 synchronized关键字详解
- Java 多线程 synchronized关键字详解
- Dreamweaver(DW)cs6安装24%时安装不了的问题
- Windows基于Apache的svn服务器配置
- 当心if
- 利用apache的mod_headers模块实现文件缓存
- 并查集
- 多线程3:Java内置锁与synchronized关键字
- appserv dos环境下运行
- 什么是QName
- android eclipse编译系统应用出现INSTALL_FAILED_UPDATE_INCOMPATIBLE 的解决
- Quartz
- 经典书籍
- 3DMax模型导入ArcGIS中发生丢失部分模型纹理的问题
- (void) (&_x == &_y)
- PHP读取PDF内容(LINUX下XPDF的配置和使用)