1、为什么需要同步
【示例代码】
public class Constant {public static int count = 0;}public class MethodA {public void process(){Constant.count++;System.out.println(Thread.currentThread().getName()+" - count="+Constant.count);}}public class MyThread01 {public static void main(String[] args) {for(int i=0;i<10;i++){Thread t = new Thread(new Runnable() {@Overridepublic void run() {MethodA methodA = new MethodA();methodA.process();}});t.start();}}}--------------Thread-4 - count=4Thread-9 - count=10Thread-6 - count=9Thread-5 - count=8Thread-0 - count=7Thread-1 - count=4Thread-2 - count=4Thread-3 - count=6Thread-7 - count=4Thread-8 - count=5
【示例代码】
public class MyThread02 {public static void main(String[] args) {MethodB methodB = new MethodB();for(int i=0;i<10;i++){Thread t = new Thread(new Runnable() {@Overridepublic void run() {methodB.process();}});t.start();}}}-------------Thread-5 - count=6Thread-1 - count=10Thread-0 - count=6Thread-8 - count=9Thread-2 - count=9Thread-4 - count=7Thread-3 - count=8Thread-6 - count=6Thread-7 - count=6Thread-9 - count=6
2、使用线程同步
public class MethodA {public void process(){synchronized(Constant.class){Constant.count++;System.out.println(Thread.currentThread().getName()+" - count="+Constant.count);}}}public class MyThread01 {public static void main(String[] args) {for(int i=0;i<10;i++){Thread t = new Thread(new Runnable() {@Overridepublic void run() {MethodA methodA = new MethodA();methodA.process();}});t.start();}}}--------------Thread-0 - count=1Thread-8 - count=2Thread-7 - count=3Thread-6 - count=4Thread-9 - count=5Thread-5 - count=6Thread-3 - count=7Thread-4 - count=8Thread-2 - count=9Thread-1 - count=10
public class MethodB {public synchronized void process(){Constant.count++;System.out.println(Thread.currentThread().getName()+" - count="+Constant.count);}}public class MyThread02 {public static void main(String[] args) {MethodB methodB = new MethodB();for(int i=0;i<10;i++){Thread t = new Thread(new Runnable() {@Overridepublic void run() {methodB.process();}});t.start();}}}-------------Thread-0 - count=1Thread-9 - count=2Thread-8 - count=3Thread-7 - count=4Thread-6 - count=5Thread-5 - count=6Thread-4 - count=7Thread-3 - count=8Thread-2 - count=9Thread-1 - count=10
线程同步,指某一个时刻,指允许一个线程来访问共享资源,线程同步其实是对对象加锁,如果对象中的方法都是同步方法,那么某一时刻只能执行一个方法,采用线程同步解决以上的问题,我们只要保证线程一操作count时,另一个线程不允许操作即可,只有线程一使用完成count后,再让线程二来使用count变量
3、为每一个线程创建一个对象来解决线程安全问题
public class ThreadTest13 {public static void main(String[] args) {Runnable r1 = new Processor();Thread t1 = new Thread(r1, "t1");t1.start();//再次创建Processor对象//每个线程拥有自己的对象Runnable r2 = new Processor();Thread t2 = new Thread(r2, "t2");t2.start();}}class Processor implements Runnable {//定义成员变量s,作为累加变量private int s = 0;public void run() {for (int i=0; i<10; i++) {s+=i;}System.out.println(Thread.currentThread().getName() + ", s=" + s);s = 0;}}
以上输出完全正确,每个线程操作的是自己的对象,没有操作共享的资源
4、Java多线程之死锁的出现和解决方法
1、什么是死锁?
死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.
形象的说就是:一个宝藏需要两把钥匙来打开,同时间正好来了两个人,他们一人一把钥匙,但是双方都再等着对方能交出钥匙来打开宝藏,谁都没释放自己的那把钥匙.就这样这俩人一直僵持下去,直到开发人员发现这个局面.
2、synchronized嵌套.
死锁例子
class ProductThreadA implements Runnable{@Overridepublic void run() {synchronized (Dead.lockA){System.out.println("ThreadA lock lockA");synchronized (Dead.lockB){System.out.println("ThreadA lock lockB");}}}}class ProductThreadB implements Runnable{@Overridepublic void run() {synchronized (Dead.lockB){System.out.println("ThreadB lock lockB");synchronized (Dead.lockA){System.out.println("ThreadB lock lockA");}}}}class Dead {final static Object lockA = new Object();final static Object lockB = new Object();public static void main(String[] args) {//这里运行线程ProductThreadA productThreadA = new ProductThreadA();ProductThreadB productThreadB = new ProductThreadB();Thread threadA = new Thread(productThreadA);Thread threadB = new Thread(productThreadB);threadA.start();threadB.start();}}
3、死锁出现的原因
同时竞争同一个资源(锁)
4、死锁的解决方法
保证不存在竞争资源(锁)即可
