java中的synchronized
来源:互联网 发布:java文件上传下载原理 编辑:程序博客网 时间:2024/05/21 15:42
一.线程进程
class MyThread extends Thread {public static int number;public void run() {for (int i = 0; i < 12; i++) {System.out.println(getName() + ":" +number++);}}}public class A {//private int i = 0;////public synchronized void a(int a) {//i++;//System.out.println(i + "");////}//public synchronized void b() {//System.out.println("sdsd");//}public static void main(String[] args) {// TODO Auto-generated method stubnew MyThread().start();new MyThread().start();}}
执行结果是:
Thread-0:0Thread-1:1Thread-0:2Thread-1:3Thread-1:5Thread-1:6Thread-0:4Thread-1:7Thread-0:8Thread-1:9Thread-0:10Thread-1:11Thread-0:12Thread-1:13Thread-0:14Thread-0:16Thread-1:15Thread-0:17Thread-1:18Thread-0:19Thread-1:20Thread-0:2Thread-1:22Thread-0:23
这个执行结果是不确定性的,上面的例子,两个线程访问静态变量number,它们获取系统时间片的时刻是不确定的,所有它们对index的访问和修改总是穿插进行的。想要解决上面的情况, 也就是以某种顺序来确保该资源在某一时刻只能被一个线程使用,不然运行结果不安全。简单来讲:A线程需要使用某个资源,如果该资源正在被线程B使用,同步机制就会让A线程一直等待,直到线程B结束 对该资源的使用,线程A才能使用。要想实现同步操作,必须获得每一个线程对象的锁。实现同步有三种方式:synchronized,wait(),notify(),Lock(JDK5中加入)。下面探讨synchorized.:
二、synchronized的用法
例子:
public class A { public void a(){ System.out.println("方法a开始执行"); for(int i = 0;i<20;i++){ System.out.println("1111"); } System.out.println("方法a执行完毕"); } public void b(){ System.out.println("方法b开始执行"); for(int i = 0;i<20;i++){ System.out.println("2222"); } System.out.println("方法b执行完毕"); }public static void main(String[] args) {// TODO Auto-generated method stubA a = new A();new Thread(new Runnable() {//开启线程@Overridepublic void run() {// TODO Auto-generated method stuba.a();}}).start();new Thread(new Runnable() {//开启线程@Overridepublic void run() {// TODO Auto-generated method stuba.b();}}).start();}}
结果:
方法a开始执行
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
方法b开始执行
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
方法b执行完毕
1111
1111
1111
方法a执行完毕
可见 两个线程同时执行。
修改用synchronzied来修饰方法:
public class A {public synchronized void a() {System.out.println("方法a开始执行");for (int i = 0; i < 20; i++) {System.out.println("1111");}System.out.println("方法a执行完毕");}public synchronized void b() {System.out.println("方法b开始执行");for (int i = 0; i < 20; i++) {System.out.println("2222");}System.out.println("方法b执行完毕");}public static void main(String[] args) {// TODO Auto-generated method stubA a = new A();new Thread(new Runnable() {// 开启线程1@Overridepublic void run() {// TODO Auto-generated method stuba.a();}}).start();new Thread(new Runnable() {// 开启线程2@Overridepublic void run() {// TODO Auto-generated method stuba.b();}}).start();}}
输出结果:
方法a开始执行
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
1111
方法a执行完毕
方法b开始执行
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
2222
方法b执行完毕
可见,线程2需要等待线程1完成后才执行。
如果创建两个不同实例来执行同一个方法呢?
public class A {public synchronized void a(int index) {System.out.println("方法a开始执行");for (int i = 0; i < 20; i++) {System.out.println("index:"+index);}System.out.println("方法a执行完毕");}//public synchronized void b() {//System.out.println("方法b开始执行");//for (int i = 0; i < 20; i++) {//System.out.println("2222");//}//System.out.println("方法b执行完毕");//}public static void main(String[] args) {// TODO Auto-generated method stubA a1 = new A();A a2 = new A();new Thread(new Runnable() {// 开启线程@Overridepublic void run() {// TODO Auto-generated method stuba1.a(10);}}).start();new Thread(new Runnable() {// 开启线程@Overridepublic void run() {// TODO Auto-generated method stuba2.a(20);}}).start();}}
输出结果:
方法a开始执行
index:10
index:10
index:10
index:10
index:10
index:10
index:10
index:10
index:10
index:10
方法a开始执行
index:10
index:20
index:10
index:20
index:10
index:20
index:10
index:20
index:10
index:20
index:10
index:10
index:10
index:10
index:20
index:10
index:20
方法a执行完毕
index:20
index:20
index:20
index:20
index:20
index:20
index:20
index:20
index:20
index:20
index:20
index:20
index:20
方法a执行完毕
可见,没有构成线程同步,那么当synchronized修饰普通方法时,如果多个线程访问一个对象的不同synchronized方法时,是可以构成同步,因为是用一个锁。当多个线程如果访问不同对象的synchronized方法时,不能构成同步,因为没有持有同一把锁。
如果是synchronized修饰静态方法?
public class A {public static synchronized void a(int index) {System.out.println("线程1:方法a开始执行");try {System.out.println("线程1:方法执行中");Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("线程1:方法a执行完毕");}public static synchronized void b() {System.out.println("线程2:方法b开始执行");try {System.out.println("线程2:方法执行中");Thread.sleep(500);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("线程2:方法b执行完毕");}public static void main(String[] args) {// TODO Auto-generated method stubA a1 = new A();A a2 = new A();new Thread(new Runnable() {// 开启线程@Overridepublic void run() {// TODO Auto-generated method stuba1.a(10);}}).start();new Thread(new Runnable() {// 开启线程@Overridepublic void run() {// TODO Auto-generated method stuba2.b();}}).start();}}
执行结果:
线程1:方法a开始执行
线程1:方法执行中
线程1:方法a执行完毕
线程2:方法b开始执行
线程2:方法执行中
线程2:方法b执行完毕
可分析:静态方法是属于类的,而对静态方法的同步等同于对类进行同步,虽然a1和a2属于不同的对象,但它们属于synchorized类的实例,所以只能顺序执行a,b方法,不能并发执行。
那么synchorized修饰代码块?
public class A {public void a(int index) {System.out.println("线程1:方法a开始执行");try {synchronized(this){System.out.println("线程1:方法执行中");Thread.sleep(3000);}} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("线程1:方法a执行完毕");}public void b() {System.out.println("线程2:方法b开始执行");try {synchronized(this){System.out.println("线程2:方法执行中");Thread.sleep(500);}} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("线程2:方法b执行完毕");}public static void main(String[] args) {// TODO Auto-generated method stubA a1 = new A();//A a2 = new A();new Thread(new Runnable() {// 开启线程@Overridepublic void run() {// TODO Auto-generated method stuba1.a(10);}}).start();new Thread(new Runnable() {// 开启线程@Overridepublic void run() {// TODO Auto-generated method stuba1.b();}}).start();}}
线程1:方法a开始执行
线程1:方法执行中
线程2:方法b开始执行
线程2:方法执行中
线程1:方法a执行完毕
线程2:方法b执行完毕
也就是两个线程都进入各自的方法去执行,但是线程2进入同步代码块时,需要线程1的同步代码块执行完才能执行。
- Java中的synchronized关键字
- java中的synchronized关键字
- java中的synchronized关键字
- java中的synchronized关键字
- java中的synchronized
- Java中的synchronized关键字
- java中的synchronized关键字
- Java中的synchronized总结
- java中的synchronized认识
- Java中的synchronized关键字
- java中的synchronized关键字
- java中的Synchronized 实现
- java中的synchronized理解
- java中的synchronized关键字
- JAVA中的synchronized详解
- JAVA中的synchronized
- java中的synchronized
- java中的synchronized
- 进程和线程的定义、区别、联系、其他
- 鸡兔同笼,共98个头,386只脚,编程计算鸡、兔各多少只
- 6.5华氏温度转化为摄氏温度
- jquery chosen这个插件 可以实现 拼音搜索
- Android 常用工具类
- java中的synchronized
- (一)算法--查找算法顺序查找和二分查找(递归和非递归方式)
- 编程规范
- 利用java8 stream api 实现List集合分页获取工具
- localStorage、cookie的使用总结
- TensorFlow学习记录1-一些比较好的学习资源
- Java编程题1
- 软考总结
- A Multiplication Game 博弈