多线程,同步代码块 当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完, 另一个线程参与进来执行。导致共享数据的错误。 解决办法: 对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。 Java对于多线程的安全问题提供了专业的解决方式。就是同步代码块。 synchronized(对象) { 需要被同步的代码 } 对象如同锁。持有锁的线程可以在同步中执行.没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。 火车上的卫生间---经典。 同步的前提: 1,必须要有两个或者两个以上的线程。 2,必须是多个线程使用同一个锁。 必须保证同步中只能有一个线程在运行。 好处:解决了多线程的安全问题。 弊端:多个线程需要判断锁,较为消耗资源, 同步代码块synchronized
1. class Ticket implements Runnable 2. { 3. private int tick = 1000; 4. Object obj = new Object(); 5. public void run() 6. { 7. while(true) 8. { 9. synchronized(obj)//创建的同步代码块 10. { 11. if(tick>0) 12. { 13. try{Thread.sleep(10);}catch(Exceptione){}//抛出异常 14. System.out.println(Thread.currentThread().getName()+"....sale:"+tick--); 15. } 16. } 17. } 18. } 19. } 22. class TicketDemo2 23. { 24. public static void main(String[] args) 25. { 26. 27. Ticket t = new Ticket(); 28. 29. Thread t1 = new Thread(t); 30. Thread t2 = new Thread(t); 31. Thread t3 = new Thread(t); 32. Thread t4 = new Thread(t); 33. t1.start(); 34. t2.start(); 35. t3.start(); 36. t4.start(); 37. } 38. }
同步代码块放在函数上的应用 2. 需求: 银行有一个金库.有两个储户分别存300员,每次存100,存3次。 6. 目的:该程序是否有安全问题,如果有,如何解决? 8. 如何找问题: 9. 1,明确哪些代码是多线程运行代码。 10. 2,明确共享数据。 11. 3,明确多线程运行代码中哪些语句是操作共享数据的。 12. 13. */ 14. 15. class Bank 16. { 17. private int sum; 18. //Object obj = new Object(); 19. public synchronized void add(int n)// synchronized放在封装的方法上更方便 20. { 21. //synchronized(obj) 22. //{ 23. sum = sum + n; 24. try{Thread.sleep(10);}catch(Exception e){} 25. System.out.println("sum="+sum); 26. //} 27. } 28. } 29. 30. class Cus implements Runnable 31. { 32. private Bank b = new Bank(); 33. public void run() 34. { 35. for(int x=0; x<3; x++) 36. { 37. b.add(100); 38. } 39. } 40. } 41. 43. class BankDemo 44. { 45. public static void main(String[] args) 46. { 47. Cus c = new Cus(); 48. Thread t1 = new Thread(c); 49. Thread t2 = new Thread(c); 50. t1.start(); 51. t2.start(); 52. } 53. } 54.
|