当前位置: 代码迷 >> Android >> Android中多线程研究(三)——线程同步和互斥及死锁
  详细解决方案

Android中多线程研究(三)——线程同步和互斥及死锁

热度:55   发布时间:2016-04-28 05:32:25.0
Android中多线程研究(3)——线程同步和互斥及死锁

为什么会有线程同步的概念呢?为什么要同步?什么是线程同步?先看一段代码:

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被两个线程同时操作,这样就很容易导致误操作。如何才能解决这个问题呢?用线程的同步技术,加上synchronized关键字

	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();    }}





  相关解决方案