Java教程

Java多线程(4)--线程的同步解决线程安全问题

本文主要是介绍Java多线程(4)--线程的同步解决线程安全问题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

多线程出现安全问题

问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。

解决办法:
对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。


Java对于多线程的安全问题提供了专业的解决方式:同步机制


方式一:同步代码块

synchronized(同步监视器){
	//需要被同步的代码
}

说明:
1.操作共享数据的代码,即为需要被同步的代码。
2.共享数据:多个线程共同操作的变量,比如: 车票就是共享数据。
3.同步监视器,俗称:锁,任何一个类的对象,都可以充当锁。(但是要求:多个线程必须共用同一把锁,即同一个对象)(可以考虑用this充当)(可以考虑类.class充当)

示例:
①Runnable接口实现类

public class MThread implements Runnable{
    private int ticket = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while (true) {
            synchronized (obj) {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + ":票号为" + ticket);
                    ticket--;
                } else break;
            }
        }
    }
}

②创建并执行多线程

public class TestThread {
    public static void main(String[] args) {
        MThread thread = new MThread();

        Thread curThread1 = new Thread(thread);
        Thread curThread2 = new Thread(thread);
        Thread curThread3 = new Thread(thread);

        curThread1.setName("窗口一");
        curThread2.setName("窗口二");
        curThread3.setName("窗口三");

        curThread1.start();
        curThread2.start();
        curThread3.start();
    }
}

同步的方式,解决了线程的安全问题。
操作同步代码时,只能有一 个线程参与, 其他线程等待,相当于是一个单线程的过程,效率低。

注意:在继承Thread类这种情况下,需要将同步同步监视器声明为静态的,这样才能保证同一把锁。


方式一:同步方法

synchronized还可以放在方法声明中,表示整个方法为同步方法。

public synchronized void show (){ //其实是有一个同步监视器(锁)this
	//需要被同步的代码
}

与同步代码块使用类似,只是在run()方法中调用该同步方法。

注意:和使用同步代码块一样,在继承Thread类这种情况下,需要将该同步方法声明为静态的,即public static synchronized void show (),此时的同步监视器相当于是当前类.class

同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。
非静态的同步方法,同步监视器是: this
静态的同步方法,同步监视器是:当前类本身

这篇关于Java多线程(4)--线程的同步解决线程安全问题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!