男儿欲遂平生志,六经勤向窗前读。这篇文章主要讲述Android多线程研究——线程同步和相互排斥及死锁相关的知识,希望能为你提供帮助。
【Android多线程研究——线程同步和相互排斥及死锁】为什么会有线程同步的概念呢?为什么要同步?什么是线程同步?先看一段代码:
package com.maso.test; public class ThreadTest2 implements Runnable{ private TestObj testObj = new TestObj(); public static void main(String[] args) { ThreadTest2 tt = new ThreadTest2(); Thread t1 = new Thread(tt, " thread_1" ); Thread t2 = new Thread(tt, " thread_2" ); t1.start(); t2.start(); } @Override public void run() {for(int j = 0; j < 10; j++){ int i = fix(1); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println(Thread.currentThread().getName() + " :i = " + i); } } public int fix(int y){ return testObj.fix(y); } public class TestObj{ int x = 10; public int fix(int y){ return x = x - y; } } }
输出结果后,就会发现变量x被两个线程同一时候操作。这样就非常easy导致误操作。
怎样才干解决问题呢?用线程的同步技术。加上synchronizedkeyword
public synchronized int fix(int y){ return testObj.fix(y); }
加上同步后,就能够看到有序的从9输出到-10.
假设加到TestObj类的fix方法上能不能实现同步呢?
public class TestObj{ int x = 10; public synchronized int fix(int y){ return x = x - y; } }
假设将synchronized加到方法上则等价于
synchronized(this){ }
能够推断出两个线程使用的TestObj类的同一个实例testOjb,所以后实现同步,可是输出的结果却不是理想的结果。这是由于当A线程运行完x = x - y后还没有输出则B线程已经进入開始运行x = x - y.
所以像以下这样输出就不会有什么问题了:
public class TestObj{ public TestObj(){ System.out.println(" 调用了构造函数" ); }int x = 10; public synchronized int fix(int y){ x = x - y; System.out.println(Thread.currentThread().getName() + " :x = " + x); return x; } }
假设将外部的fix方法改动例如以下:
public int fix(int y){ ax++ ; if(ax%2 == 0){ return testObj.fix(y, testObj.str1); }else{ return testObj.fix(y, testObj.str2); } }
public class TestObj{ String str1 = " a1" ; String str2 = " a2" ; public TestObj(){ System.out.println(" 调用了构造函数" ); }int x = 10; public int fix(int y, String str){ synchronized (str) { x = x - y; System.out.println(Thread.currentThread().getName() + " :x = " + x); } return x; } }
此时synchronized中的str对象不是同一个对象,所以两个线程所持有的对象锁不是同一个,这样就不能实现同步。
要实现线程之间的相互排斥就要使用同一个对象锁。
什么是死锁呢?举个样例就是比方你和同学租了个两室的房子,你拿着你房子的钥匙。你同学拿着他房子的钥匙,如今你在房子等你同学将他的钥匙给你然后你进他房子。你同学在他的房子等你将钥匙给他然后他进你的房子,这样就死锁了。
package com.maso.test; public class ThreadDieSock implements Runnable { private int flag = 1; private Object obj1 = new Object(), obj2 = new Object(); public void run() { System.out.println(" flag=" + flag); if (flag == 1) { synchronized (obj1) { System.out.println(" 我已经锁定obj1,歇息0.5秒后锁定obj2去!" ); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj2) { System.out.println(" 1" ); } } } if (flag == 0) { synchronized (obj2) { System.out.println(" 我已经锁定obj2,歇息0.5秒后锁定obj1去。" ); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj1) { System.out.println(" 0" ); } } } }public static void main(String[] args) { ThreadDieSock run01 = new ThreadDieSock(); ThreadDieSock run02 = new ThreadDieSock(); run01.flag = 1; run02.flag = 0; Thread thread01 = new Thread(run01); Thread thread02 = new Thread(run02); System.out.println(" 线程開始喽!
" ); thread01.start(); thread02.start(); } }
推荐阅读
- 比真机还快的Android模拟器——Genymotion
- 最新的office2013激活密钥分享_其它办公
- office2013官方版哪里下载?office2013官方下载地址_其它办公
- 如何查看office2013版本?查看office2013版本的办法_其它办公
- Excel2013设置数据有效果性办法_Excel专区
- WPS Office 2016抢鲜版要激活码怎样办?_WPS office
- Office 2013将Excel表格转换成PDF文档的办法_Excel专区
- 如何屏幕截图?用office2013进行屏幕截图的办法_其它办公
- 含下载地址与激活工具 office 2016安装与激活图文详细教程_其它办公