synchronized基本介绍:
- 在非静态方法前使用,相当于使用this锁;
- 在静态方法前使用,相当于使用类锁;
- 还可以对某变量进行加锁,object锁;
- 静态方法中不可以使用this锁,非静态方法中可以使用类锁,静态方法、非静态方法都可以对object进行加锁;
- 类锁、this锁、object锁是相互独立的,不会互相阻塞;
public synchronized void fun5() {
System.out.println("实例" + id + "--fun2!!!");
}
//等价于
public void fun5() {
synchronized(this){
System.out.println("实例" + id + "--fun2!!!");
}
}
public static void fun5() {
System.out.println("实例"+id+"--fun2!!!");
}
//等价于
public void fun5() {
synchronized (Test9.class) {
System.out.println("实例" + id + "--fun2!!!");
}
}
public void fun5(Object num) {
synchronized(Test9.class){
System.out.println("实例" + id + "--fun2!!!");
}
synchronized (num){
System.out.println("这是一个Object锁!!!");
}
}
//下面这种方法,this锁是会报错的
public static void fun6(Object num) {
synchronized(this){
System.out.println("实例" + id + "--fun2!!!");
}
synchronized (num){
System.out.println("这是一个object锁!!!");
}
}
synchronized(*.class)类锁的相关介绍:
1、当加了类锁的方法或代码块处于访问状态时,该类的其他加了类锁的方法或代码块将拒绝其他线程的访问,但是其他线程可以访问该类的普通方法或者未被占用的this锁或object锁。只有当该方法或代码块执行完毕,其他线程才能访问该类的类锁(注意是方法执行完毕,而不是线程执行完毕。)
- 相关代码演示
//公共类,线程阻塞时间
class Sleep {
public static void sleepForSecond(int num) throws InterruptedException {
TimeUnit.SECONDS.sleep(num * 5);
}
}
//synchronized 关键字探索 --- 静态方法
public class Test9_1 {
public static void main(String[] args) throws Exception{
IsStatic isStatic = new IsStatic(1);
IsStatic isStatic2 = new IsStatic(2);
int num = 0;
new Thread(() -> {
try {
isStatic.fun1();
Sleep.sleepForSecond(2);
System.out.println("线程1阻塞完毕!!!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "A").start();
new Thread(() -> {
isStatic.fun2();
}, "B").start();
new Thread(() -> {
isStatic.fun3();
}, "C").start();
new Thread(() -> {
try {
isStatic.fun4();
}catch (Exception e){}
}, "D").start();
new Thread(() -> {
isStatic2.fun2();
}, "B").start();
//写个循环计时
while (true) {
System.out.print((++num) + " 秒:");
Sleep.sleepForSecond(1);
}
}
}
class IsStatic {
private int id;
public IsStatic(int id){
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void fun1() throws InterruptedException {
synchronized (IsStatic.class) {
Sleep.sleepForSecond(2);
System.out.println("实例"+id+"--fun1!!!");
Sleep.sleepForSecond(5);
}
}
public void fun2() {
synchronized (IsStatic.class) {
System.out.println("实例"+id+"--fun2!!!");
}
}
public void fun3() {
System.out.println("实例"+id+"--fun3!!!");
}
public void fun4() throws InterruptedException {
synchronized (this) {
Sleep.sleepForSecond(5);
System.out.println("实例"+id+"--fun4!!!");
}
}
}
synchronized(this)对象锁的相关介绍:
1、 当加了this锁(对象锁)处于访问状态时,那么该对象的其他this锁(对象锁)将拒绝其他线程访问,但是它的普通方法或者加了类锁、object锁只要不被其他线程占有,其他线程依然可以进行访问。只有当该方法或代码块执行完毕,其他线程才能访问该对象的对象锁(注意是对象锁,同一个类的不同对象,他们之间的对象锁是没有任何关系的,只有处于同一个对象,他们的对象锁才会发生阻塞。)
2、 代码演示:
//synchronized关键字探索-非静态方法
public class Test9 {
public static void main(String[] args) throws Exception {
noStatic noStatic = new noStatic(1);
noStatic noStatic2 = new noStatic(2);
int num = 0;
new Thread(() -> {
try {
noStatic.fun1();
Sleep.sleepForSecond(2);
System.out.println("线程1阻塞完毕!!!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "A").start();
new Thread(() -> {
noStatic.fun2();
}, "B").start();
new Thread(() -> {
noStatic.fun3();
}, "C").start();
new Thread(() -> {
noStatic2.fun2();
}, "B").start();
new Thread(() -> {
try {
noStatic.fun4();
} catch (Exception e) {
}
}, "B").start();
//写个循环计时
while (true) {
System.out.print((++num) + " 秒:");
Sleep.sleepForSecond(1);
}
}
}
//this 锁 非静态方法
class noStatic {
private int id;
public noStatic(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void fun1() throws InterruptedException {
synchronized (this) {
Sleep.sleepForSecond(2);
System.out.println("实例" + id + "--fun1!!!");
Sleep.sleepForSecond(5);
}
}
public void fun2() {
synchronized (this) {
System.out.println("实例" + id + "--fun2!!!");
}
}
public void fun3() {
System.out.println("实例" + id + "--fun3!!!");
}
public void fun4() throws InterruptedException {
synchronized (noStatic.class) {
Sleep.sleepForSecond(2);
System.out.println("实例" + id + "--fun4!!!");
}
}
}
synchronized(object)变量锁的相关介绍:
1、 当object锁(对象锁)处于占用状态时,不管是在同一实例,同一类的不同实例,不同对象的不同实例中,只要和该对象共用同一块内存地址(常量池或堆),并对其增加了同步锁修饰,那么这些变量锁将拒绝其他线程的访问,除非那个处于占用状态的锁执行完毕。
2、代码演示
public class Test9_2 {
public static void main(String[] args) throws Exception{
IsObject isObject = new IsObject();
Integer num1 = 1;
Integer num2 = 1;
Integer num3 = new Integer(1);
int num = 0;
//开三个线程进行验证
new Thread(() ->{
try {
isObject.fun1(num1);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"A").start();
new Thread(() ->{IsObject.fun2(num2);},"B").start();
new Thread(() ->{IsObject.fun2(num3);},"C").start();
//写个循环计时
while (true) {
System.out.print((++num) + " 秒:");
Sleep.sleepForSecond(1);
}
}
}
class IsObject{
public void fun1(Integer num) throws InterruptedException {
synchronized (num){
System.out.println("fun1线程"+Thread.currentThread().getName()+"的num:"+num);
Sleep.sleepForSecond(5);
}
}
public static void fun2(Integer num){
synchronized (num){
System.out.println("fun2线程" + Thread.currentThread().getName() + "的num:" + num);
}
}
}

414

被折叠的 条评论
为什么被折叠?



