java中synchronized的使用和理解
来源:互联网 发布:为什么要激活windows 编辑:程序博客网 时间:2024/05/29 17:20
首先说一下Java的同步机制:保证在同一时间只有一个线程可以操作对应资源,避免多个线程同时访问相同资源发生冲突。synchronize是java中的一个关键字,它是一种同步锁,可以实现同步机制。
synchronized常用的几种方式:
1. synchronized修饰普通方法
2. synchronize修饰静态方法
3. synchron修饰代码块
下面我把自己写的demo来进行说明
1:synchronized修饰普通方法
public class A { int num = -1; public A() { num = 0; } public synchronized void a() { for (int i = 0; i < 5; i++) { num += 1; try { Thread.sleep(10); System.out.println(Thread.currentThread().getName() +">>>>>>>>>>"+ num); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
public class Main { public static void main(String[] args) { A a = new A(); new Thread(new Runnable() { public void run() { a.a(); } }).start(); new Thread(new Runnable() { public void run() { a.a(); } }).start(); }}
打印结果:
Thread-0>>>>>>>>>>1
Thread-0>>>>>>>>>>2
Thread-0>>>>>>>>>>3
Thread-0>>>>>>>>>>4
Thread-0>>>>>>>>>>5
Thread-1>>>>>>>>>>6
Thread-1>>>>>>>>>>7
Thread-1>>>>>>>>>>8
Thread-1>>>>>>>>>>9
Thread-1>>>>>>>>>>10
恩,不错,确实是实现了在同一时间内,只有一个线程能访问对应的资源,其他的线程必须的等其结束了才能开始运行。
好,那么我修改一下main中的代码呢?
public class Main { public static void main(String[] args) { A a1 = new A(); A a2= new A(); new Thread(new Runnable() { public void run() { a1.a(); } }).start(); new Thread(new Runnable() { public void run() { a2.a(); } }).start(); }}
打印出来的结果是:
Thread-0>>>>>>>>>>1
Thread-1>>>>>>>>>>1
Thread-0>>>>>>>>>>2
Thread-1>>>>>>>>>>2
Thread-0>>>>>>>>>>3
Thread-1>>>>>>>>>>3
Thread-1>>>>>>>>>>4
Thread-0>>>>>>>>>>4
Thread-0>>>>>>>>>>5
Thread-1>>>>>>>>>>5
咦,这个结果怎么是这样?可以看出两个线程开启后,开始进行交叉运行。这样不对啊!!!应该等第一个线程结束,第二个线程才能开始运行啊。那么问题就来了,那么我就开始说一下这个事情。
synchronize修饰普通的方法时,是对象锁。也就是说在多线程中使用同一个对象访问synchronized修饰的方法可以达到同步的效果。但是如果在不同的线程中使用不同对象去调用其修饰的方法则达不到同步的效果。
2.修饰静态方法
public class A { static int num = -1; byte[] lock = new byte[0]; public A() { num = 0; } public static synchronized void a() { for (int i = 0; i < 5; i++) { num += 1; try { Thread.sleep(10); System.out.println(Thread.currentThread().getName() + ">>>>>>>>>>" + num); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
public class Main { public static void main(String[] args) { new Thread(new Runnable() { public void run() { A.a(); } }).start(); new Thread(new Runnable() { public void run() { A.a(); } }).start(); }}
打印结果:
Thread-0>>>>>>>>>>0
Thread-0>>>>>>>>>>1
Thread-0>>>>>>>>>>2
Thread-0>>>>>>>>>>3
Thread-0>>>>>>>>>>4
Thread-1>>>>>>>>>>5
Thread-1>>>>>>>>>>6
Thread-1>>>>>>>>>>7
Thread-1>>>>>>>>>>8
Thread-1>>>>>>>>>>9
synchronized修饰的静态方法,这种情况下的锁是包含这个方法的类的锁,也是这个类对象的锁。所以多线程访问时,可以达到同步的效果。
3.修饰代码块
public class A { static int num = -1; byte[] lock = new byte[0]; public A() { num = 0; } public void printfLog() { synchronized (lock) { for (int i = 0; i < 5; i++) { num += 1; try { Thread.sleep(10); System.out.println(Thread.currentThread().getName() + ">>>>>>>>>>" + num); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
public class Main { public static void main(String[] args) { A a1 = new A(); A a2 = new A(); new Thread(new Runnable() { public void run() { a1.printfLog(); } }).start(); new Thread(new Runnable() { public void run() { a2.printfLog(); } }).start(); }}
打印结果:
Thread-0>>>>>>>>>>2
Thread-1>>>>>>>>>>3
Thread-0>>>>>>>>>>4
Thread-1>>>>>>>>>>5
Thread-0>>>>>>>>>>6
Thread-1>>>>>>>>>>7
Thread-0>>>>>>>>>>8
Thread-1>>>>>>>>>>9
Thread-0>>>>>>>>>>10
Thread-1>>>>>>>>>>10
这中结果和synchronize修饰的普通方法类似。在多线程中不同对象的进行调用,不能实现同步的效果。
注意:
1.在多线程中同一个对象进行调用,可以实现同步的效果 .可自行尝试一下。
2.将lock换成this时,打印的效果是一样的。
那么我将代码改动一下呢?
public class A { static int num = -1; byte[] lock = new byte[0]; public A() { num = 0; } public void printfLog() { synchronized (A.class) { for (int i = 0; i < 5; i++) { num += 1; try { Thread.sleep(10); System.out.println(Thread.currentThread().getName() + ">>>>>>>>>>" + num); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
打印结果如下:
Thread-0>>>>>>>>>>1
Thread-0>>>>>>>>>>2
Thread-0>>>>>>>>>>3
Thread-0>>>>>>>>>>4
Thread-0>>>>>>>>>>5
Thread-1>>>>>>>>>>6
Thread-1>>>>>>>>>>7
Thread-1>>>>>>>>>>8
Thread-1>>>>>>>>>>9
Thread-1>>>>>>>>>>10
所以这样的效果跟synchronize修饰静态方法一样。这样就可以在不同线程中不同的对象调用时实现同步的效果。
下面说一下synchronize修饰方法和代码块的区别:
synchronize修饰方法时,控制整个方法。
synchronize修饰代码块时,只控制代码块(只有代码块之内的才能实现同步效果)。而对于代码块之外的代码,则不受控制(也就是不能实现同步的效果)。
简单一点说就是:synchronize修饰代码块时,更加灵活精确。
- java中synchronized的使用和理解
- Java 中synchronized的理解
- Java中Synchronized和Lock的使用
- Java中Synchronized和Lock的使用
- Java中Synchronized和Lock的使用
- Java中Synchronized和Lock的使用
- 对 Java 中 synchronized(this) 的一些理解和认识
- java中synchronized理解与使用
- 深入理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别
- Java中synchronized的使用
- Java中Synchronized和Lock的使用和区别
- Java中Synchronized和Lock的使用和区别
- 对java中synchronized的一点理解
- Java中synchronized关键字的简单理解
- Java synchronized的理解
- java 多线程 Synchronized方法和方法块 synchronized(this)和synchronized(object)的理解
- java 多线程 Synchronized方法和方法块 synchronized(this)和synchronized(object)的理解
- Java多线程中Synchronized简介和Static Synchronized的区别
- Windows网络守门人UserLock更新至v9.6,可通过Webhooks获取实时登录通知
- 挑战程序设计竞赛-第四版-3.1.4 最大化平均值
- 关于802.11帧格式中为什么会有三个(或四个)地址?
- ubuntu 安装开发工具
- ubuntu 忘记用户名及密码解决办法
- java中synchronized的使用和理解
- 浅析Java语言与C++语言的区别
- 【慕课网实战课程笔记】Vue.js高仿饿了么外卖App
- 小玩具——温度采集项目(八)
- 几维安全最新APP加密神器,国内首款全平台移动代码虚拟机KiwiVM即将发布
- 关联、组合、聚合、依赖关系比较
- 机器学习_非参数估计
- python zip(*args)
- 11.6 一道简单2-SAT题 BZOJ1823