JAVA 多线程——线程竞争
来源:互联网 发布:打开淘宝网首页 编辑:程序博客网 时间:2024/05/16 06:06
下面再来看一个关于线程竞争的例子,记得学过了操作系统课程里对线程的进程做过了一定程度的讲解,但当时对于所谓的同步和互斥方法也并不是很了解。最好的方法还是通过代码来理解
class Acount{ public static int money = 100; public static void save(int count) { money += count; } public static void get(int count) { money -= count; } public static void show() { System.out.println(money); } public static int getMoney() { return money; }}
首先这里提供了一个银行账号,我们可以通过静态方法来进行取钱、存钱的基本操作。
再来看下面的实现run的接口
class MyRunnable implements Runnable { private int i = 0; @Override public void run() { for (i = 0; i < 10; i++) { if(Acount.getMoney() > 0) { Acount.get(80); } Acount.show(); try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Acount.save(80); Acount.show(); } }}
实现了runable的接口的类,提供了对于这个账号的操作方法。
每一次在取钱之前,先判断是否会透支,若透支,则不取钱了。
以下是Main方法
public class Main{ public static void main(String[] args) { Thread thread1 = new Thread(new MyRunnable()); Thread thread2 = new Thread(new MyRunnable()); thread1.start(); thread2.start(); }}
有两个账号对其经行操作
-60-6020-6020-6020-6020-60
这是是运行结果,可以看出来在判断在大于80的情况依然取钱了,这是由于是判断钱够不够,再取钱,所以这两个步骤之前有空隙。导致了这一种情况。
- 利用lock来解决
这种情况可以利用lock来进行解决,具体代码如下
class MyRunnable implements Runnable { private int i = 0; private static final Lock loc = new ReentrantLock(); @Override public void run() { loc.lock(); for (i = 0; i < 10; i++) { if(Acount.getMoney() > 80) { Acount.get(80); Acount.show(); try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Acount.save(80); Acount.show(); } } loc.unlock(); }}
几乎是没有什么不同的,知识在run方法中加入了lock的lock()和unLock()方法,来保证一定要执行完这一整套,才让其他的线程来访问这一套方法。
- synchronized 方法
对于这个一直把我搞得好糊涂,有时候用synchronized(this)发现不能做到吧{代码}这一块中做到原子访问。后面看别人的博客发现了synchronized(this)是对于对象而言的。
简而言之 就是synchronized(this)是对于该方法属于的对象而言的,在run()方法中使用synchronized(this)只是会使对于MyRunable的对象进行锁定,而我在main中是使用了两个对象,所以不会起到锁的效果。
因此应该改成synchronized(lock) 其中lock得是一个静态的属性,若不是静态的属性会发生什么情况?请看下面的代码
class MyRunnable implements Runnable { private int i = 0; private static final Lock loc = new ReentrantLock(); private Acount asd = new Acount(); @Override public void run() { synchronized (asd) { for (i = 0; i < 10; i++) { if(Acount.getMoney() > 80) { System.out.println(Thread.currentThread()); Acount.get(80); Acount.show(); try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Acount.save(80); Acount.show(); } System.out.println(Thread.currentThread()); } } }}
运行之后依然会不同步,这是因为这个对象每一个类的单独有一个。不能保证共享的情况,若把它改成static便可以共享了
0 0
- JAVA 多线程——线程竞争
- java多线程竞争
- C++——多线程编程(二)std::mutex 线程同步、解决资源竞争问题
- 竞争条件——线程学习四
- Java多线程——线程
- java线程同步——竞争条件的荔枝+锁对象
- 多线程竞争
- Java 多线程 竞争造成的异常
- java多线程(二)解决共享资源竞争
- java资源竞争问题(线程互斥)
- java资源竞争问题(线程互斥)
- Java多线程——1 中断线程
- Java多线程——线程池
- java多线程——线程池
- java多线程——线程同步问题
- Java多线程——线程状态
- Java 多线程 —— 线程池
- JAVA多线程——线程的中断
- 【原创】python urllib/reque…
- 【原创】 shell一键配置squid高匿…
- 创建线程
- 【原创】Mac os pip&nbs…
- 【原创】selenium 等待某个元…
- JAVA 多线程——线程竞争
- 【原创】Mac os 一次蓝屏修复
- 【原创】反编译Android apk,提取*.…
- 【原创】Macbook 修改 ls 时间格式
- 【原创】python requests&nbs…
- banner使用
- 【原创】Java JNI 参数
- 【原创】Java HttpClient&nbs…
- PHP中include引用jpgraph时出现问题