广州网站整站优化,一起做网站郑州,wordpress press,wordpress用户前端化synchronized方法、synchronized块 线程的同步不安全的线程示例1#xff1a;示例2示例3 synchronized方法、synchronized块 线程的同步 并发#xff1a;同一个对象被多个线程同时操作。 解决方案#xff1a;让多个线程排队操作对象。 使用队列和锁解决多线程的并发问题。 同… synchronized方法、synchronized块 线程的同步不安全的线程示例1示例2示例3 synchronized方法、synchronized块 线程的同步 并发同一个对象被多个线程同时操作。 解决方案让多个线程排队操作对象。 使用队列和锁解决多线程的并发问题。 同进程的多线程共享同一块存储空间当多个线程同时访问某块内存空间时就存在并发问题。为了保证数据在方法中被访问时的正确性在访问时加入锁机制synchronized当线程获得对象的排它锁该线程独占资源其他线程必须等待其使用后释放锁即可。 同时也伴随着一些问题 一个线程持有锁导致其它线程所有需要此锁的线程挂起在多线程竞争下加锁释放锁会导致比较多的上下文切换和调度延时导致性能问题也可能存在优先级高的线程等待优先级低的线程释放锁而导致性能问题。 不安全的线程 通过下面例子说明线程是不安全。 重复执行下面方法执行结果可能会有多种情况。 示例1
//每次执行结果都不是我们预想的结果
public class UnsafeBuyTicket {public static void main(String[] args) {BuyTicket buyTicket new BuyTicket();new Thread(buyTicket,张三).start();new Thread(buyTicket,李四).start();new Thread(buyTicket,王五).start();}
}class BuyTicket implements Runnable {private int ticketNums 10;boolean flag true;Overridepublic void run() {while (flag) {buy();}}//synchronized 同步方法 锁的是this 即BuyTicket对象private /**synchronized*/ void buy() {if (ticketNums 0) {flag false;return;}try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() 买到票 ticketNums--);}
}张三买到票9
李四买到票8
王五买到票10
李四买到票7
王五买到票6
张三买到票7
张三买到票5
李四买到票4
王五买到票5
李四买到票3
张三买到票3
王五买到票3
王五买到票2
张三买到票2
李四买到票2
李四买到票1
王五买到票1
张三买到票1示例2
public class UnsafeBank {public static void main(String[] args) {Account funds new Account(家庭基金, 100);new TakeMoney(funds,60,you).start();new TakeMoney(funds,80,youWife).start();}}class Account{String name;int money;public Account(String name, int money) {this.name name;this.money money;}
}class TakeMoney extends Thread{Account account;int takeMoney;//取多钱钱int nowMoney;//你口袋里面的钱public TakeMoney(Account account, int takeMoney, String name) {super(name);this.account account;this.takeMoney takeMoney;}//synchronized run 是不行的Overridepublic void run() {//synchronized (account) {if ((account.money - takeMoney) 0) {System.out.println(Thread.currentThread().getName() 余额不足。);return;}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}account.money account.money - takeMoney;nowMoney nowMoney takeMoney;System.out.println(account.name 余额为 account.money);System.out.println(this.getName() 口袋里面的钱 nowMoney);//}}
}//执行结果
家庭基金余额为-40
家庭基金余额为-40
you口袋里面的钱60
youWife口袋里面的钱80示例3
public class UnsafeList {public static void main(String[] args) throws InterruptedException {ListString list new ArrayListString();for (int i 0; i 10000; i) {new Thread(() - {//synchronized (list) {list.add(Thread.currentThread().getName());// }}).start();}Thread.sleep(3000);//确保上面线程能够执行完毕后在打印list.sizeSystem.out.println(list.size());}
}//执行结果
9999针对上面示例添加synchronized关键字使其变为线程安全的。 synchronized方法、synchronized块 关键字synchronized可以修饰方法或者以同步块的形式来进行使用它主要确保多个线程在同一个时刻只能有一个线程处于方法或者同步块中它保证了线程对变量访问的可见性和排他性。 synchronized方法控制对象的访问每个对象对应一把锁每个synchronized方法都必须获得该方法对象的锁才能执行否则会阻塞线程方法执行时独占该锁知道方法执行完毕才会释放锁。 同步块synchronized(object){} synchronized修饰的代码块会在object对象上加一个监视器。而同步方法会在当前对象this上增加一个监视器。 synchronized同步代码块一般加载共享资源对象上。 //示例1 将buy方法改为同步方法private synchronized void buy()//示例2 试图按照示例1的方案 将run方法改为同步方法验证是不行的因为加上run方法的synchronized将对TakeMoney类添加的监视器但最终操作的确是account对象//此示例 多线程操作的共共享资源是account并非TakeMoney//示例3 在共享资源list增加synchronized关键字为其添加监视器