前言
synchronized是同步的意思,是java提供的一个关键字,用于多线程访问共享资源时,保证线程访问安全的一种手段。同时synchronized是一种可重入锁,但是是非公平锁。
一、对象锁
用法一 同步代码块
java 万物皆对象,多线程的情况下,锁对象必须是同一个,也就是多个线程共享一把锁资源。
synchronized(锁对象){
//同步代码块
}
案例
synchronized关键字结合notity()方法和wait()方法实现多线程交替打印。
package hchang.demo.Lock;
/**
* synchronized 配合wait()和notify()方法实现两个线程的交替打印
* sycnronized 用法:对象锁(同步代码块)
* 锁对象在语法上可以是任意一个对象,但是对象必须是同一个,也就是多线程之间公用一把锁
*/
public class SynchronizedDemo {
static String str1= "ABCDEFG";
static String str2 = "123456";
public static void main(String[] args){
Object ot = new Object();
char[] char1 = str1.toCharArray();
char[] char2 = str2.toCharArray();
Thread td1 = new Thread(new Runnable() {//匿名内部类
@Override
public void run() {
synchronized (ot) {
//同步代码块 ot是锁对象
for (char c:char1) {
System.out.println(c);
ot.notify();
try {
ot.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ot.notify();//谁先完成叫醒对方,否则永远有一个线程在wait,程序无法结束
}
}
},"ThreadA");
Thread td2 = new Thread(new Runnable() {
@Override
public void run() {
//同步代码块 ot是锁对象
synchronized (ot) {
for (char c:char2) {
System.out.println(c);
ot.notify();
try {
ot.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ot.notify();//谁先完成叫醒对方,否则永远有一个线程在wait,程序无法结束
}
}
},"ThreadB");
td1.start();
td2.start();
}
}
用法二 同步方法
synchronized关键字修饰非静态方法,锁的对象是this,就是当前非静态方法所在的类的对象。
修饰符 synchronized 返回值类型 方法名(形参列表){
//同步方法体
}
案例
一个线程使用同步代码块,一个线程使用同步方法,实现用户同步订购商品。
package hchang.demo.Lock;
/**
* synchronized 用法:对象锁
*
*/
public class SynchronizedClassDemo {
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
ThreadB threadB = new ThreadB(threadA);
threadB.start();
threadA.start();
}
}
class ThreadB extends Thread{
private Object lock;
public ThreadB(Object lock) {
this.lock = lock;
}
@Override
public void run() {
Bshopping();
}
public void Bshopping() {
synchronized (lock) {
System.out.println("用户B浏览商品");
System.out.println("用户B加入购物车");
System.out.println("用户B提交订单");
System.out.println("用户B支付");
}
}
}
class ThreadA extends Thread{
@Override
public void run() {
Ashopping();
}
/**
* synchronized 加在实例方法上,代表锁对象是this
*/
public synchronized void Ashopping() {
System.out.println("用户A浏览商品");
System.out.println("用户A加入购物车");
System.out.println("用户A提交订单");
System.out.println("用户A支付");
}
}
二、类锁
synchronized关键字修饰静态方法,锁的对象是类对象,就是当前静态方法所在的类的字节码对象。
修饰符 synchronized static 返回值类型 方法名(形参列表){
//同步方法体
}
案例
一个线程使用同步代码块,一个线程使用静态同步方法,实现用户同步订购商品。
package hchang.demo.Lock;
/**
* synchronized 用法:类锁
* 1、类锁只有一把锁 对象锁可以有多个
* 2、class 对象只有一个
*/
public class SynchronizedClassDemo {
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
ThreadB threadB = new ThreadB(threadA.getClass());
threadB.start();
threadA.start();
}
}
class ThreadB extends Thread{
private Object lockClass;
public ThreadB(Object lockClass) {
this.lockClass = lockClass;
}
@Override
public void run() {
Bshopping();
}
public void Bshopping() {
synchronized (lockClass) {
System.out.println("用户B浏览商品");
System.out.println("用户B加入购物车");
System.out.println("用户B提交订单");
System.out.println("用户B支付");
}
}
}
class ThreadA extends Thread{
@Override
public void run() {
Ashopping();
}
/**
* synchronized 加在静态方法上,代表锁对象是当前对象的字节码对象,也就是类对象
*/
public synchronized static void Ashopping() {
System.out.println("用户A浏览商品");
System.out.println("用户A加入购物车");
System.out.println("用户A提交订单");
System.out.println("用户A支付");
}
}