Java基础巩固之线程的同步synchronized
来源:互联网 发布:工作证在线生成软件 编辑:程序博客网 时间:2024/06/06 05:12
Java中的synchronized关键字,可以用来修饰方法和代码块,主要是为了保证在同一时刻只有一条线程访问被修饰的代码。
synchronized分为对象级别的同步和类级别的同步。
1、当使用synchronized关键字修饰普通方法时,如果已经有一条线程访问此方法,那么其他使用同一对象调用此方法的线程,需要等待此线程执行完成后释放对象锁才能执行该方法,同时需要注意的是也无法执行当前对象中使用synchronized修饰的其他方法,但是可以执行非synchronized修饰的方法
2、当使用static synchronized关键字修饰普通方法时,如果已经有一条线程访问此方法,那么其他使用此类的任何实例化对象调用此方法的线程,需要等待此线程执行完成后释放锁才能执行该方法,同时需要注意的是也无法执行类中使用synchronized或者static synchronized修饰的其他方法,但是可以执行非synchronized修饰的方法
来一段代码,看看在没使用synchronized关键字同步代码时,用两个线程访问同一资源是否会出现问题
Outputer类包含output方法,用于打印字符
class Outputer{ public synchronized void output(String str) { int len = str.length(); for(int i = 0; i < len; i++) { System.out.print(str.charAt(i)); } System.out.println(); }}创建两条线程,用于调用output方法
//实例化Outputer对象static Outputer outputer = new Outputer();public static void main(String[] args){//线程1Thread t1 = new Thread(new Runnable(){@Overridepublic void run(){while(true){//调用outputer对象的outputoutputer.output("abcdefghijk");try{Thread.sleep(10);}catch (InterruptedException e){e.printStackTrace();}}}});//线程2Thread t2 = new Thread(new Runnable(){@Overridepublic void run(){while(true){//调用outputer对象的outputoutputer.output("mnopqrstuvw");try{Thread.sleep(10);}catch (InterruptedException e){e.printStackTrace();}}}});t1.start();t2.start();}
在执行过程中,出现错乱的输出:
解决方法:
1、将循环输出的代码,放到synchronized同步代码块中
class Outputer{ public void output(String str) { String sync = ""; /* * 1、两条线程使用的是同一个outputer对象,所以可以使用"this" * 2、由于用一个对象中的"sync"变量只会存在一份,所以也可以使用"sync"变量来控制 */ synchronized (this/*sync*/) { int len = str.length(); for(int i = 0; i < len; i++) { System.out.print(str.charAt(i)); } System.out.println(); } }}
2、用synchronized关键字修饰方法
class Outputer{ /** * 普通方法需要类的实例化对象来调用,所以synchronized修饰的方法也只针对于同一个对象 * @param str */ public synchronized void output(String str) { int len = str.length(); for(int i = 0; i < len; i++) { System.out.print(str.charAt(i)); } System.out.println(); }}
以上方法只在多条线程使用同一个Outputer()对象实例调用output方法时起作用,如果每条线程都使用不同的Outputer()实例对象,则还是会出现错乱现象。
解决方法:
1、使用 static synchronized修饰方法
class Outputer{ /** * 静态方法的调用不依赖于任何实例化对象,是类级别的方法。 * 所以synchronized控制的是类级别 * @param str */ public static synchronized void output(String str) { int len = str.length(); for(int i = 0; i < len; i++) { System.out.print(str.charAt(i)); } System.out.println(); }}
2、在synchronized块的参数中传入字节码对象
class Outputer{ public void output(String str) { /** * 类的字节码也是一个Class对象,且在JVM中是唯一存在的 */ synchronized (Outputer.class) { int len = str.length(); for(int i = 0; i < len; i++) { System.out.print(str.charAt(i)); } System.out.println(); } }}
0 0
- Java基础巩固之线程的同步synchronized
- java基础巩固之-线程
- java基础巩固---(线程)锁机制:synchronized、Lock、Condition
- java线程同步之synchronized
- java线程之同步synchronized
- Java基础-多线程-③线程同步之synchronized
- Java基础-多线程-③线程同步之synchronized
- Java基础-多线程-③线程同步之synchronized
- java基础(九)之深入剖析线程同步Synchronized,Lock
- Java基础巩固之线程学习
- Java基础巩固之线程学习
- java多线程之synchronized(线程同步)
- Java多线程-3 线程同步之synchronized
- java并发编程-线程同步之synchronized
- java 线程同步 synchronized
- java 线程同步 synchronized
- java synchronized 线程同步
- Java 线程同步 synchronized
- jquery库推荐-superslide
- JavaScript中的作用域以及this变量
- 小白linux bash 学习前奏二 vi操作
- 国际赛事 中国魅力——天南铜都“中国东川泥石流国际汽车越野赛”
- 为什么你应该(从现在开始就)写博客
- Java基础巩固之线程的同步synchronized
- 今天天气不错
- Openstack-卸载
- 第七周作业
- 回调函数例子
- [hdu-2041] 超级楼梯
- 回调函数例子
- 小白linux bash 学习前奏三 创建用户
- 模拟和仿真