简介
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
- 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
- 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
- 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
- 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
synchronized和lock区别:
1.synchronized是一个内置的java关键字;lock是一个java类
2.synchronized无法判断锁状态;lock可以判断锁状态;
3.synchronized会自动释放锁;lock必须手动释放锁;
4.synchronized获取锁(线程A获得锁,阻塞其他线程;线程B被阻塞,一直傻傻等);lock就不一定会傻傻等;
5.synchronized是可重入锁,不可中断的锁,非公平锁;lock是可重入锁 非公平(可以自己设置);
6.synchronized适合少量的代码同步问题;lock适合大量的同步代码;
实例代码
描述:标准情况下,两个线程谁先打印。
代码语言:javascript复制public class ThreadDemo {
public static void main(String[] args) throws Exception{
Phone phone = new Phone();
new Thread(() -> {
phone.sendSms();
}, "A").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.call();
}, "A").start();
}
}
class Phone {
// synchronized锁的对象是方法的调用者 谁先拿到,谁先执行
public synchronized void sendSms() {
System.out.println("发短信");
}
// synchronized锁的对象是方法的调用者
public synchronized void call() {
System.out.println("打电话");
}
}
发短信
打电话
描述:sendSms延迟4秒,两个线程谁先打印。
代码语言:javascript复制public class ThreadDemo {
public static void main(String[] args) throws Exception{
Phone phone = new Phone();
new Thread(() -> {
phone.sendSms();
}, "A").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.call();
}, "A").start();
}
}
class Phone {
// synchronized锁的对象是方法的调用者 谁先拿到,谁先执行
public synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("发短信");
}
// synchronized锁的对象是方法的调用者
public synchronized void call() {
System.out.println("打电话");
}
}
发短信
打电话
描述:新增一个普通方法hello
代码语言:javascript复制public class ThreadDemo3 {
public static void main(String[] args) throws Exception{
Phone3 phone = new Phone3();
new Thread(() -> {
phone.sendSms();
}, "A").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.hello();
}, "A").start();
}
}
class Phone3 {
// synchronized锁的对象是方法的调用者 谁先拿到,谁先执行
public synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("发短信");
}
// synchronized锁的对象是方法的调用者
public synchronized void call() {
System.out.println("打电话");
}
public void hello() {
System.out.println("你好呀");
}
}
你好呀
发短信
描述:两个对象调用两个同步方法
代码语言:javascript复制public class ThreadDemo4 {
public static void main(String[] args) throws Exception{
// 两个对象
Phone4 phone = new Phone4();
Phone4 phone2 = new Phone4();
new Thread(() -> {
phone.sendSms();
}, "A").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone2.call();
}, "A").start();
}
}
class Phone4 {
// synchronized锁的对象是方法的调用者 谁先拿到,谁先执行
public synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("发短信");
}
// synchronized锁的对象是方法的调用者
public synchronized void call() {
System.out.println("打电话");
}
}
打电话
发短信
描述:增加两个静态的同步方法,在一个对象和两个对象的前提下。
代码语言:javascript复制public class ThreadDemo5 {
public static void main(String[] args) throws Exception{
Phone5 phone = new Phone5();
new Thread(() -> {
phone.sendSms();
}, "A").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.call();
}, "A").start();
}
}
class Phone5 {
// static静态方法,属于类的,所以锁的是类Class
public static synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("发短信");
}
// synchronized锁的对象是方法的调用者
public static synchronized void call() {
System.out.println("打电话");
}
}
发短信
打电话
public class ThreadDemo5 {
public static void main(String[] args) throws Exception{
Phone5 phone = new Phone5();
Phone5 phone2 = new Phone5();
new Thread(() -> {
phone.sendSms();
}, "A").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone2.call();
}, "A").start();
}
}
class Phone5 {
// static静态方法,属于类的,所以锁的是类Class
public static synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("发短信");
}
// static静态方法,属于类的,所以锁的是类Class
public static synchronized void call() {
System.out.println("打电话");
}
}
发短信
打电话
描述:一个静态同步方法,一个普通同步方法;在一个对象和两个对象的前提下。
代码语言:javascript复制public class ThreadDemo6 {
public static void main(String[] args) throws Exception{
Phone6 phone = new Phone6();
new Thread(() -> {
phone.sendSms();
}, "A").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.call();
}, "A").start();
}
}
class Phone6 {
// static静态方法,属于类的,所以锁的是类Class
public static synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("发短信");
}
// synchronized锁的对象是方法的调用者
public synchronized void call() {
System.out.println("打电话");
}
}
打电话
发短信
public class ThreadDemo6 {
public static void main(String[] args) throws Exception{
Phone6 phone = new Phone6();
Phone6 phone2 = new Phone6();
new Thread(() -> {
phone.sendSms();
}, "A").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone2.call();
}, "A").start();
}
}
class Phone6 {
// static静态方法,属于类的,所以锁的是类Class
public static synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("发短信");
}
// synchronized锁的对象是方法的调用者
public synchronized void call() {
System.out.println("打电话");
}
}
打电话
发短信