在多线程程序中,它们多个线程之间是共享一块内存的。java
当某个线程正在读取该内存块的信息时,并在修改内存信息的同时,并在此发生意外,如:阻塞,若是有别的线程也进来访问这块内存,而且也要修改该内存块的信息,这是就会发生意想不到的错误。编程
好比:你有一个银行帐户,帐户里面有2000块钱。多线程
一天,你拿着银行本子去银行取钱,打算取1500,而后银行的工做人员就会经过电脑程序检查你的帐户中是否有超过1500的钱,查询以后,证实你的帐户有超过1500,能够取款,而后响应取款的程序!固然,你取款程序执行完以后,才会从你的帐户减去1500,然而就在执行取款程序的同时,也就是还没从你的帐户里减去1500;巧的是,这时你的老妈/老爸拿着你的银行卡也在l另外一处的取款机上取钱,取款机同时也会去检查你的帐户里的钱有没有超过1500,这时固然超过1500,而后你老妈取钱成功啦,你也取钱成功,而后大家家取了3000块,卡里还剩500,这种好事多好啊。ide
。。。。。学习
固然,这种事情是不会发生的,哈哈!!spa
要解决上面这个问题,咱们就得了解程序的原子性这个概念。线程
也就是说保证一个程序或者某个代码块完整执行的性质,在这个过程中,别的线程若是想执行该代码块时是没有权限的。code
还有若是在执行过程,忽然中断该程序,程序的内存信息是不会修改的。对象
对象锁。有了对象锁,就保证了在一个线程执行某个代码块的时候,别的线程就不访问到该代码块了,就避免了像上面那样形成数据混乱了。blog
以下模仿一个多窗口售票的程序:
没有关键字synchronize以前:
1 package com.thread.Synchronized; 2 3 /** 4 * 线程同步 5 * --》synchronized关键字 6 * 7 * 模拟一个多窗口售票的例子 8 * 9 * @author hunjun 10 */ 11 public class TestSync implements Runnable{ 12 private static int ticketNum = 200; 13 14 public static void main(String[] args) { 15 TestSync ts1 = new TestSync(); 16 TestSync ts2 = new TestSync(); 17 TestSync ts3 = new TestSync(); 18 19 Thread t1 = new Thread(ts1,"窗口一"); 20 Thread t2 = new Thread(ts2,"窗口二"); 21 Thread t3 = new Thread(ts3,"窗口三"); 22 23 t1.start(); 24 t2.start(); 25 t3.start(); 26 } 27 28 @Override 29 public void run() { 30 // TODO Auto-generated method stub 31 try { 32 while(ticketNum > 0){ 33 Thread.sleep(2000); 34 TestSync.saleTicket(); 35 } 36 } catch (InterruptedException e) { 37 // TODO Auto-generated catch block 38 e.printStackTrace(); 39 } 40 } 41 42 public static void saleTicket(){ 43 if(ticketNum > 0){ 44 //开始售票 45 System.out.println(Thread.currentThread().getName()+"售出第 "+ticketNum+" 张票。。"); 46 ticketNum --; 47 } 48 } 49 50 }
结果;
窗口一售出第 200 张票。。
窗口二售出第 200 张票。。
窗口三售出第 200 张票。。
窗口一售出第 197 张票。。
窗口三售出第 197 张票。。
窗口二售出第 197 张票。。
数据很混乱。。。由于在当前线程sleep的时候别先进来来,改变数据,就会出现混乱。
加了关键字synchronize以后
package com.thread.Synchronized; /** * 线程同步 * --》synchronized关键字 * * 模拟一个多窗口售票的例子 * * @author hunjun */ public class TestSync implements Runnable{ private static int ticketNum = 200; public static void main(String[] args) { TestSync ts1 = new TestSync(); TestSync ts2 = new TestSync(); TestSync ts3 = new TestSync(); Thread t1 = new Thread(ts1,"窗口一"); Thread t2 = new Thread(ts2,"窗口二"); Thread t3 = new Thread(ts3,"窗口三"); t1.start(); t2.start(); t3.start(); } @Override public void run() { // TODO Auto-generated method stub try { while(ticketNum > 0){ Thread.sleep(2000); TestSync.saleTicket(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
/*在这里加了关键字synchronized*/ public static synchronized void saleTicket(){ if(ticketNum > 0){ //开始售票 System.out.println(Thread.currentThread().getName()+"售出第 "+ticketNum+" 张票。。"); ticketNum --; } } }
结果:
窗口三售出第 200 张票。。
窗口二售出第 199 张票。。
窗口一售出第 198 张票。。
窗口一售出第 197 张票。。
窗口二售出第 196 张票。。
窗口三售出第 195 张票。。
窗口一售出第 194 张票。。
窗口二售出第 193 张票。。
窗口三售出第 192 张票。。
总结:多线程是java中很重要的知识点,涉及不少编程的概念,好比还有死锁问题,线程池什么的。
请继续关注。。。。
若是您认为哪里有什么问题欢迎一块儿学习,沟通解决!!