synchronized关键字详解(一)
2024-08-31 02:05:09
synchronized官方定义:
同步方法支持一种简单的策略防止线程干扰和内存一致性错误,如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的(这一个synchronized关键字完成的)。
通俗的来讲:
synchronized关键字:能够保证同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。
synchronized的两个用法:
1.对象锁:包括方法锁(默认锁对象是当前实例对象)和同步代码块锁(自己指定锁的对象);
2.类锁:synchronized修饰的静态的方法或指定锁为Class对象;
代码展示:
对象锁:针对的是同一个对象(即下列中的instance对象),如果是两个不同的对象,对象锁就不能起到同步的作用(可以自己创两个对象测试),而类锁可以。
* 对象锁的代码块形式
* @author Administrator
*
*/
public class SynchronizeTest01 implements Runnable{
static SynchronizeTest01 instance = new SynchronizeTest01();
Object obj = new Object();
@Override
public void run() {
//锁自定义对象
synchronized (obj) {
System.out.println("我是对象锁代码块,我叫"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"玩完了");
}
//第一种锁当前对象
/*synchronized (this) {
System.out.println("我是对象锁代码块,我叫"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"玩完了");
}*/
}
public static void main(String[] args) {
Thread t1 = new Thread(instance,"线程一");
Thread t2 = new Thread(instance,"线程二");
t1.start();
t2.start();
while(t1.isAlive()||t2.isAlive()) { }
System.out.println("执行结束");
}
}
/**
* 普通方法锁形式
* @author Administrator
*
*/
public class SynchronizeTest02 implements Runnable{
static SynchronizeTest02 instance = new SynchronizeTest02();
@Override
public void run() {
//调用加synchronized关键字的普通方法
method();
}
public synchronized void method() {
System.out.println("我是普通方法锁,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "玩完了");
}
public static void main(String[] args) {
Thread t1 = new Thread(instance,"线程一");
Thread t2 = new Thread(instance,"线程二");
t1.start();
t2.start();
while(t1.isAlive()||t2.isAlive()) { }
System.out.println("执行结束");
}
}
普通方法锁形式
类锁:每个类可能会有多个对象,但是每个类只有一个Class对象,所以类锁的本质就是对Class对象的锁,类锁在同一时刻只能被一个对象拥有(对象锁不可以)
类锁的第一种形式:在静态方法上加锁,并创建了两个对象,依然可以解决并发问题。
/**
*
* 类锁的第一种形式:静态方法锁形式
* @author Administrator
*
*/
public class SynchronizeTest02 implements Runnable{
static SynchronizeTest02 instance1 = new SynchronizeTest02();
static SynchronizeTest02 instance2 = new SynchronizeTest02();
@Override
public void run() {
//调用加synchronized关键字的静态方法
method();
}
public static synchronized void method() {
System.out.println("我是静态方法锁,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "玩完了");
}
public static void main(String[] args) {
Thread t1 = new Thread(instance1,"线程一");
Thread t2 = new Thread(instance2,"线程二");
t1.start();
t2.start();
while(t1.isAlive()||t2.isAlive()) { }
System.out.println("执行结束");
}
}
类锁的第二种形式:
/**
*
* 类锁的第二种形式:代码块锁.Class形式
* @author Administrator
*
*/
public class SynchronizeTest03 implements Runnable{
static SynchronizeTest03 instance1 = new SynchronizeTest03();
static SynchronizeTest03 instance2 = new SynchronizeTest03();
@Override
public void run() {
//调用加synchronized关键字的普通方法
method();
}
public void method() {
synchronized (SynchronizeTest03.class) {
System.out.println("我是静态方法锁,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "玩完了");
}
}
public static void main(String[] args) {
Thread t1 = new Thread(instance1,"线程一");
Thread t2 = new Thread(instance1,"线程二");
t1.start();
t2.start();
while(t1.isAlive()||t2.isAlive()) { }
System.out.println("执行结束");
}
}
锁代码块中锁.Class形式
最新文章
- Java面试(1)-- Java逻辑运算符
- 当您尝试从 64 位 SQL Server 客户端上运行分布式的查询到链接的 32 位 SQL Server 时,您可能会收到一条错误消息
- uname -r和uname -a了解
- NSLog说明
- Text Reverse
- win10亮度不能调节的解决方法
- 再谈协方差矩阵之主成分分析PCA
- .c和.h档
- IAM
- Markdown初入门(使用Typora编辑)
- 原生JS实现选中的radio变为未选中
- oracle总结--增删改查
- 【转】Java HashMap的死循环
- js补零方法
- C#常见几道面试题
- 安装OpenOffice
- Service Intent must be explicit的解决方法
- sqlconnection 调用webservice服务
- Android /system/build.prop 文件
- Unity c#反射查找类中符合条件的方法并执行