java线程同步与互斥
来源:互联网 发布:java 分布式事务 编辑:程序博客网 时间:2024/06/06 21:38
同步:用关键字synchronized给针对共享资源的操作(方法或代码块)加锁,这把锁就叫作互斥锁。所以有两种加锁方式,一种是同步方法,一种是同步代码块。如图:
特别提示:锁住的不是方法,也不是代码块,而是对象,并且是同一个对象。也就是说一个线程正在调用该对象的同步方法,如果还没有执行完成,那么另一个线程就无法调用该对象的所有同步方法或代码块(会阻塞),当然没有加synchronized关键字的方法或代码块不会被锁住。
示例代码1:
class ShareObj{String[] colors1={"red","orange","yellow", "green","blue","indigo","purple","black","white"};String[] colors2={"红色","橙色","黄色", "绿色","蓝色","靛色","紫色","黑色","白色"};synchronized void printColor(String thName){if(thName.equals("color")){for(int i=0;i<colors1.length;i++){try {System.out.println(colors1[i]);Thread.sleep((long)(Math.random()*2000));} catch (InterruptedException e) {e.printStackTrace();}}}else if(thName.equals("颜色")){for(int i=0;i<colors2.length;i++){try {System.out.println(colors2[i]);Thread.sleep((long)(Math.random()*2000));} catch (InterruptedException e) {e.printStackTrace();}}}}}class CreateByThread extends Thread{ShareObj obj=null;public CreateByThread(String name,ShareObj obj){super(name);this.obj=obj;}public void run() {obj.printColor(this.getName());}}public class ThreadSynExc {public static void main(String[] args) {ShareObj obj=new ShareObj();CreateByThread cbt1=new CreateByThread("color",obj);CreateByThread cbt2=new CreateByThread("颜色",obj);cbt1.start();cbt2.start();}}
如果printColor方法没有加synchronized关键字,运行结果如下:
红色
redorangeyellow橙色green黄色绿色blue蓝色indigopurple靛色紫色blackwhite黑色白色
这就是两个线程都在调用printColor方法的结果,相互竞争资源,没有规律。
如果我们要求一个线程在调用printColor的时候,其它线程不能调用,我们就可以在printColor前面加上synchronized关键字
运行结果如下所示:
红色橙色黄色绿色蓝色靛色紫色黑色白色redorangeyellowgreenblueindigopurpleblackwhite
示例代码2:
public class Bank {private int balance =0;//账户余额 //存钱 public void addMoney(int money){ System.out.println("======存钱start======="); balance +=money; System.out.println(System.currentTimeMillis()+"存进:"+money); System.out.println("账户余额:"+balance); System.out.println("======存钱end======="); } //取钱 public void subMoney(int money){ System.out.println("======取钱start======="); if(balance-money < 0){ System.out.println("余额不足"); System.out.println("======取钱end======="); return; } balance -=money; System.out.println(+System.currentTimeMillis()+"取出:"+money); System.out.println("账户余额:"+balance); System.out.println("======取钱end======="); } }public class SyncBankTest {public static void main(String[] args) {final Bank bank=new Bank(); Thread tadd=new Thread(new Runnable() { public void run() { while(true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } bank.addMoney(100); } } }); Thread tsub = new Thread(new Runnable() { public void run() { while(true){ bank.subMoney(100); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }); tsub.start(); tadd.start(); }}
如果不加synchronized关键字,运行结果是这样的:
======存钱start=======1505238241890存进:100账户余额:100======存钱end=============取钱start=======1505238242890取出:100账户余额:0======存钱start=============取钱end=======1505238242890存进:100账户余额:100======存钱end=============取钱start=======1505238243890取出:100账户余额:0======取钱end=============存钱start=======1505238243890存进:100账户余额:100======存钱end=======
是不是看起来很混乱,看不明白存钱取钱是怎么回事?
如果在存钱和取钱的方法上加上synchronized关键字,运行结果如下所示:
======取钱start=======余额不足======取钱end=============存钱start=======1505238048821存进:100账户余额:100======存钱end=============取钱start=======1505238048834取出:100账户余额:0======取钱end=============存钱start=======1505238049821存进:100账户余额:100======存钱end=============取钱start=======1505238049834取出:100账户余额:0======取钱end=============存钱start=======1505238050821存进:100账户余额:100======存钱end=============取钱start=======1505238050834取出:100账户余额:0======取钱end=======
怎么样,是不是感觉可以理解了!!
示例代码3:
class SyncCla { public synchronized void test() { System.out.println("test开始.."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("test结束.."); } } class MyThread extends Thread { public void run() { SyncCla sync = new SyncCla(); sync.test(); } } public class Main { public static void main(String[] args) { for (int i = 0; i < 3; i++) { Thread thread = new MyThread(); thread.start(); } } }
运行结果:
test开始..test开始..test开始..test结束..test结束..test结束..
可以看出来,上面的程序起了三个线程,同时运行SyncCla类中的test()方法,虽然test()方法加上了synchronized,但是还是同时运行起来,貌似synchronized没起作用。因为SyncCla被new了三次,每个线程分别是一个不同对象,所以synchronized不起作用了
说明synchronized关键字是对同一对象加锁!!!!切记切记!
阅读全文
0 0
- java 线程同步与互斥
- 【Java】线程并发、互斥与同步
- JAVA线程的同步与互斥
- java线程同步与互斥
- java线程系列---关于线程同步与互斥问题
- 线程同步与互斥
- 线程互斥与同步
- 线程同步与互斥
- 线程同步与互斥
- 线程同步与互斥
- 线程同步与互斥
- 线程同步与互斥
- 线程互斥与线程同步
- java的线程问题同步与互斥
- java多线程Thread线程同步与互斥、锁机制
- BCB线程的互斥与同步
- 操作系统 进程/线程 同步与互斥
- 线程同步与互斥 synchronized()
- vim修改颜色配置
- webservice的soap风格的接口发布流程
- eclipse没有(添加)”Dynamic Web Project”选项的方法
- HDU 1878 欧拉回路(概念)
- 关于Lazarus下PowerPDF控件的使用
- java线程同步与互斥
- 利用Metasploit建立持续性会话后门
- JavaScript基础教程笔记
- NOIP 2014 D1T3 飞扬的小鸟
- mybatis的第一个程序
- mysql插入和删除多条
- 《MySQL入门很简单》学习笔记(24)之自问自答(关键词:数据库/MySQL/外键/索引/联合查找/视图/触发器)
- 文件系统---文件系统的基本概念
- DECLARE_WORK