多线程教程初级教程(一)--多线程之间的同步

1-1: 为什么有线程安全问题?

当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题。

2-1:线程安全问题代码演示?

class ThreadTrain1 implements Runnable {
    // 这是货票总票数,多个线程会同时共享资源
    private int trainCount = 100;

    @Override
    public void run() {
        while (trainCount > 0) {// 循环是指线程不停的去卖票
try {
                // 等待100毫秒
                Thread.sleep(10);
            } catch (InterruptedException e) {

            }

            sale();
        }
    }

    /**
     * 
     * @methodDesc: 功能描述:(出售火车票)
     * @author: 余胜军
     * @param:
     * @createTime:2017年8月9日 下午9:49:11
     * @returnType: void
     * @copyright:上海每特教育科技有限公司
     */
    public void sale() {
        if (trainCount > 0) {
try {
                Thread.sleep(10);
            } catch (Exception e) {

            }

            System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
            trainCount--;        }
    }
}

public class ThreadDemo2 {

    public static void main(String[] args) {

        ThreadTrain1 threadTrain = new ThreadTrain1(); // 定义 一个实例
        Thread thread1 = new Thread(threadTrain, "一号窗口");
        Thread thread2 = new Thread(threadTrain, "二号窗口");
        thread1.start();
        thread2.start();
    }

}

2-2:线程安全解决办法          

问:如何解决多线程之间线程安全问题?
答:使用多线程之间同步或使用锁(lock)。
问:为什么使用线程同步或使用锁能解决线程安全问题呢?
答:将可能会发生数据冲突问题(线程不安全问题),只能让当前一个线程进行执行。代码执行完成后释放锁,让后才能让其他线程进行执行。这样的话就可以解决线程不安全问题。
问:什么是多线程之间同步?
答:当多个线程共享同一个资源,不会受到其他线程的干扰。

3.1:使用同步代码块解决安全问题

什么是同步代码块?
答:就是将可能会发生线程安全问题的代码,给包括起来。
synchronized(同一个数据){
可能会发生线程冲突问题
}

    private Object mutex = new Object();// 自定义多线程同步锁
    public void sale() {
        synchronized (mutex) {
            if (trainCount > 0) {
try {
                    Thread.sleep(10);
                } catch (Exception e) {
                }
                System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
                trainCount--;            }
        }
    }

3-2:使用同步函数解决线程安全问题

什么是同步函数?
答:在方法上修饰synchronized 称为同步函数

public synchronized void sale() {
            if (trainCount > 0) { 
try {
                    Thread.sleep(40);
                } catch (Exception e) {
                }
                System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
                trainCount--;
            }
    }

3-3:证明同步函数使用的他this锁

class ThreadTrain5 implements Runnable {
    // 这是货票总票数,多个线程会同时共享资源
    private int trainCount = 100;
    public boolean flag = true;
    private Object mutex = new Object();

    @Override
    public void run() {
        if (flag) {
            while (true) {
                synchronized (mutex) {
                    if (trainCount > 0) {
                        try {
                            Thread.sleep(40);
                        } catch (Exception e) {

                        }
                        System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
                        trainCount--;
                    }
                }
            }
        } else {
            while (true) {
                sale();
            }
        }
    }

    
    public synchronized void sale() {
        if (trainCount > 0) {
            try {
                Thread.sleep(40);
            } catch (Exception e) {

            }
            System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
            trainCount--;
        }
    }
}

public class ThreadDemo5 {

    public static void main(String[] args) throws InterruptedException {

        ThreadTrain5 threadTrain = new ThreadTrain5(); // 定义 一个实例
        Thread thread1 = new Thread(threadTrain, "一号窗口");
        Thread thread2 = new Thread(threadTrain, "二号窗口");
        thread1.start();
        Thread.sleep(40);
        threadTrain.flag = false;
        thread2.start();
    }

}

3-4:使用同步代码块

synchronized(同一个数据){
可能会发生线程冲突问题
}

       private Object mutex = new Object();// 自定义多线程同步锁
    public void sale() {
        synchronized (mutex) {
            if (trainCount > 0) {
try {
                    Thread.sleep(10);
                } catch (Exception e) {
                }
                System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
                trainCount--;            }
        }
    }

练习题

5.1、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。

 

猜你喜欢

转载自www.cnblogs.com/itcastwzp/p/10971607.html