如何实现线程安全(线程安全的解决方法,如何实现线程同步)

 问:如何解决多线程之间线程安全问题?

答:使用多线程之间同步或使用锁(lock)。

问:为什么使用线程同步或使用锁能解决线程安全问题呢?

答:将可能会发生数据冲突问题(线程不安全问题),只能让当前一个线程进行执行。代码执行完成后释放锁,让后才能让其他线程进行执行。这样的话就可以解决线程不安全问题。

问:什么是多线程之间同步?

答:当多个线程共享同一个资源,不会受到其他线程的干扰。

 

线程安全解决方法?

①使用同步代码块

问:什么是同步代码块?

答:就是用synchronized关键字将可能会发生线程安全问题的代码(就是要对全局变量或静态变量进行写操作的代码),给包括起来。

synchronized(mutex){

    可能会发生线程冲突代码

}

这个mutex是个互斥量(就是锁),自己定义一个这样的互斥量,一般定义一个对象类,哪个线程拿到这个,现在就哪个线程执行代码块中的程序,其它线程不就是就绪状态吗,等着这玩意释放。

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

注意啊:分布式情况,集群的情况下(多台服务器做出了一个集群),不能使用synchronized,synchronized只适合单个jvm.

②同步函数

什么是同步函数?

答:在方法上用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--;
	}
}

同步函数用的是什么锁?

答:同步函数使用this锁。

证明方式: 一个线程使用同步代码块(this明锁),另一个线程使用同步函数。如果两个线程抢票不能实现同步,那么会出现数据错误,能说明就是this锁。(代码如下,请直接略过,知道是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();
	}

}

 

②静态同步函数

方法上加上static关键字,使用synchronized 关键字修饰

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

静态的同步函数使用的锁是该函数所属字节码文件对象

可以用 getClass方法获取,也可以用当前  类名.class 表示。

synchronized (ThreadTrain.class) {
	System.out.println(Thread.currentThread().getName() + ",出售 第" + 
		(100 - trainCount + 1) + "张票.");
	trainCount--;
	try {
		Thread.sleep(100);
	} catch (Exception e) {
	}
}

后面一篇是多线程死锁,大大萌看看吧,点个赞吧。

发布了138 篇原创文章 · 获赞 22 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/guihaiyuan123/article/details/105542578