synchronized 初解
前言
提示:这里可以添加本文要记录的大概内容:
题主 synchronized 关键字一直用的少,今天开贴记录下其用法和特性。
提示:以下是本篇文章正文内容,下面案例可供参考
一、synchronized 用来做什么?
示例:synchronized 关键字一直被用来做同步锁,其中加锁方式有许多,比如修饰代码块,修饰方法,其作用不尽相同,话不多说直接上示例
1. 对象锁
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ThreadPoolExecutor;
public class ThreadPool {
private static ThreadPoolExecutor threadPoolExecutor;
private static String a = "a";
public ThreadPool() {
}
public void syncObjectLock() throws InterruptedException {
Thread currentThread = Thread.currentThread();
System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
synchronized (this) {
System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
currentThread.sleep(1000);
System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
static class ThreadDemo implements Runnable {
private ThreadPool threadPool;
public ThreadDemo(ThreadPool threadPool) {
this.threadPool = threadPool;
}
@Override
public void run() {
try {
threadPool.syncObjectLock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreadPool threadPool = new ThreadPool();
ThreadPool threadPool1 = new ThreadPool();
Thread thread1 = new Thread(new ThreadDemo(threadPool), "t_1");
Thread thread2 = new Thread(new ThreadDemo(threadPool), "t_2");
Thread thread3 = new Thread(new ThreadDemo(threadPool), "t_3");
Thread thread4 = new Thread(new ThreadDemo(threadPool), "t_4");
Thread thread5 = new Thread(new ThreadDemo(threadPool1), "t_5");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}
}
结果:可以看到 上文代码线程5 和线程 1 锁的是不同的对象,虽然对this 加锁,但是线程5 和 1 是同时进入同步代码块。可以看出对object 加锁在不同的实例上是锁不住的。
2.类锁
public void syncObjectLock() throws InterruptedException {
Thread currentThread = Thread.currentThread();
System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
synchronized (ThreadPool.class) { // 对 ThreadPool整个类上锁
System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
currentThread.sleep(1000);
System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
结果:可以看到 线程5 和其他线程都是排队进入的
3. 对整个方法上锁
代码如下(示例):
public synchronized void syncObjectLock() throws InterruptedException {
Thread currentThread = Thread.currentThread();
System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
currentThread.sleep(1000);
System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
结果:可以看到,线程5 和线程3 是同时进来的,方法上锁在不同的对象里边是不存在同步的
4. 锁静态变量
public void syncObjectLock() throws InterruptedException {
Thread currentThread = Thread.currentThread();
System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
synchronized (a) {
System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
currentThread.sleep(1000);
System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
结果:可以看到所有线程都是顺序执行的,所以静态变量上锁也是类级别的锁,不管多少实例都是锁住的
4. 锁静态方法
public synchronized static void syncObjectLock() throws InterruptedException {
Thread currentThread = Thread.currentThread();
System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
currentThread.sleep(1000);
System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
结果:所有线程顺序进出,作用和锁住静态变量一样
总结
对对象和方法上锁,作用级别在同一个实例中才有效,对静态变量/静态方法上锁 为类级别的锁,在整个类级别生效,不管你是否同一个实例中。