前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一篇长文讲清楚java的synchronized以及各功能代码示例

一篇长文讲清楚java的synchronized以及各功能代码示例

原创
作者头像
疯狂的KK
修改2023-03-23 17:43:11
7220
修改2023-03-23 17:43:11
举报
文章被收录于专栏:Java项目实战

Java中的synchronized关键字是一种同步机制,用于控制多个线程对共享资源的访问。在Java中,每个对象都有一个内部锁,也称为监视器锁或管程锁。当使用synchronized关键字修饰一个方法或代码块时,它会获取对象的内部锁,防止其他线程访问该对象的同步方法或代码块,直到当前线程释放锁为止。

synchronized的使用方法:

synchronized关键字可以用于修饰方法和代码块。

  1. 修饰方法

使用synchronized修饰方法时,它将锁定整个方法,即使方法中有多个代码块,也只有一个线程可以进入该方法。例如:

代码语言:txt
复制
public synchronized void method(){

//方法体

}
  1. 修饰代码块

使用synchronized修饰代码块时,它将锁定代码块中的对象,只有一个线程可以进入该代码块。代码块的格式如下:

代码语言:txt
复制
synchronized(对象){

//代码块

}

其中,对象可以是任何Java对象,但通常是被共享的对象。例如:

代码语言:txt
复制
public void method(){

    synchronized(this){

        //代码块
    }
}
  1. 静态同步方法

如果一个方法是静态的,可以使用synchronized修饰该方法。这将锁定整个类,只有一个线程可以进入该方法。例如:

代码语言:txt
复制
public static synchronized void method(){

//方法体

}

synchronized的功能:

synchronized的主要功能是保证多个线程对共享资源的安全访问。它可以防止数据竞争(数据竞争指两个或多个线程同时访问共享数据,并试图同时修改它),从而避免了线程间的冲突和数据不一致的问题。

synchronized的其他功能包括:

  1. 保证可见性

当一个线程获取对象的锁时,它将会清空本地内存中的缓存变量,并重新从主内存中获取最新的变量值。这样可以保证每个线程都看到最新的变量值,避免了线程间的数据不一致问题。

  1. 保证顺序性

synchronized关键字可以保证线程的执行顺序,即使多个线程同时访问共享资源,它们也会按照一定的顺序执行,避免了线程间的混乱和不可控性。

代码示例:

下面是一些使用synchronized关键字的示例代码:

代码语言:txt
复制
1. 修饰方法

public class MyThread extends Thread {

private int count = 5;

public synchronized void run() {

count--;

System.out.println(Thread.currentThread().getName() + " count = " + count);

}

public static void main(String[] args) {

MyThread myThread = new MyThread();

Thread t1 = new Thread(myThread, "t1");

Thread t2 = new Thread(myThread, "t2");

Thread t3 = new Thread(myThread, "t3");

Thread t4 = new Thread(myThread, "t4");

Thread t5 = new Thread(myThread, "t5");

t1.start();

t2.start();

t3.start();

t4.start();

t5.start();

}

}

输出结果:

代码语言:txt
复制
t1 count = 4

t3 count = 3

t4 count = 2

t5 count = 1

t2 count = 0
代码语言:txt
复制
2. 修饰代码块

public class MyThread extends Thread {

private int count = 5;

public void run() {

synchronized(this){

count--;

System.out.println(Thread.currentThread().getName() + " count = " + count);

}

}

public static void main(String[] args) {

MyThread myThread = new MyThread();

Thread t1 = new Thread(myThread, "t1");

Thread t2 = new Thread(myThread, "t2");

Thread t3 = new Thread(myThread, "t3");

Thread t4 = new Thread(myThread, "t4");

Thread t5 = new Thread(myThread, "t5");

t1.start();

t2.start();

t3.start();

t4.start();

t5.start();

}

}

输出结果:

代码语言:txt
复制
t1 count = 4

t2 count = 3

t3 count = 2

t4 count = 1

t5 count = 0
代码语言:txt
复制
3. 静态同步方法


public class MyThread extends Thread {

private static int count = 5;

public static synchronized void run() {

count--;

System.out.println(Thread.currentThread().getName() + " count = " + count);

}

public static void main(String[] args) {

Thread t1 = new Thread(MyThread::run, "t1");

Thread t2 = new Thread(MyThread::run, "t2");

Thread t3 = new Thread(MyThread::run, "t3");

Thread t4 = new Thread(MyThread::run, "t4");

Thread t5 = new Thread(MyThread::run, "t5");

t1.start();

t2.start();

t3.start();

t4.start();

t5.start();

}

}

输出结果:

代码语言:txt
复制
t1 count = 4

t3 count = 3

t2 count = 2

t5 count = 1

t4 count = 0

总结:

synchronized关键字是Java中的同步机制,用于控制多个线程对共享资源的访问。它可以保证多个线程对共享资源的安全访问,避免了线程间的冲突和数据不一致的问题。synchronized可以修饰方法和代码块,还可以用于保证可见性和顺序性。在实际开发中,我们应该根据具体情况选择适当的同步方式,以保证程序的正确性和性能。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档