线程同步

来源:互联网 发布:c指针数组赋值 编辑:程序博客网 时间:2024/06/06 08:35

线程安全问题的判断
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();    }        }}
0 0