线程安全问题的判断
1是否是多线程环境
2是否有共享数据
3是否有多条语句操作共享数据
解决方法:在共享数据那里添加锁,如下

synchronized(对象){
需要同步的代码;
}

线程共享数据出问题的例子:
共同使用的多线程:

package cn;

public class MyThread implements Runnable {
    private static int max = 100;

    @Override
    public void run() {

        while (true) {
            if (max > 0) {
            // 3个线程同时进来,都停在这里max=1
                try {
                    Thread.sleep(100); //3个线程同时进来,都停在这里,线程1执行完,这时max=0
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" + max--);

            }
        }
    }
}

线程没有同步出现的问题:

    public static void main(String[] args) {
        MyThread st = new MyThread();

        // 创建三个线程对象
        Thread t1 = new Thread(st, "线程1");
        Thread t2 = new Thread(st, "线程2");
        Thread t3 = new Thread(st, "线程3");


        t1.start();
        t2.start();
        t3.start();
    }
出问题的输出:

线程1:6
线程3:5
线程2:4
线程1:3
线程3:2
线程2:1
线程1:0
线程3:-1

解决方法:
1自定义锁,同步在方法上

public class MyThread implements Runnable {
    private static int max = 100;
    //创建任意锁对象
    private Object obj = new Object();
    @Override
    public void run() {

        while (true) {
            ////线程同时进来,都停在这里,等其他线程结束完才申请进去的资格
            synchronized (obj){//
                if (max > 0) {
                    try {
                        Thread.sleep(100); 
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":" + max--);
                }
        }
        }



    }
    //同步在方法上
    private  synchronized void sub(){
        if (max > 0) {
            try {
                Thread.sleep(100); 
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":" + max--);
        }
    }
}

2.锁对象Lock

package cn;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * * Lock: 
 * void lock(): 获取锁。
 * void unlock():释放锁。  
 * ReentrantLock是Lock的实现类.
 * @author Administrator
 *
 */

public class MyThread implements Runnable {
    private static int max = 100;
    //创建任意锁对象
    private Object obj = new Object();
    // 定义锁对象
    private Lock lock=new ReentrantLock();//ReentrantLock是Lock的实现类.
    @Override
    public void run() {



        //lock的实现
        while (true) {
        ////线程同时进来,都停在这里,等其他线程结束完才申请进去的资格
            lock.lock();
            if (max > 0) {
                try {
                    Thread.sleep(100); 
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" + max--);
            }
            lock.unlock();
    }
        }



}
posted on 2017-04-06 22:13  2637282556  阅读(123)  评论(0编辑  收藏  举报