被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否是线程安全

1 被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否线程安全?

/**
 * (1)被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否线程安全?
 * (2)线程安全问题都是由全局变量及静态变量引起的,若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;
 *     若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能导致数据不一致
 * (3)线程安全是指多个线程在执行同一段代码的时候采用加锁机制,线程不安全就是不提供加锁机制保护
 * (4)在下面的例子中,如果method2方法都是通过method1调用的,那么程序执行没有问题,是线程安全的,但是method2也有可能同时被其他的线程调用,可能会对全局变或者静态变量进行修改,所以说method2线程不安全
 */
public class SynchronizedDemo1 {

    public static void main(String[] args) {
        new Thread(() -> {
            method1();
        }).start();

        new Thread(() -> {
            method2();
        }).start();
    }

    private static synchronized void method1() {
        method2();
    }

    private static void method2() {
        System.out.println(Thread.currentThread().getName() + "进入非Synchronized方法");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "结束非Synchronized方法");
    }

}

 

2多个方法同步

/**
 * synchronized可以实现方法的同步,a()和b()方法同步了,因为他们使用的是同一的对象
 * 总结synchronized和lock的区别
 * (1)synchronized关键字不能继承,如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,
 *    而必须显式地在子类的这个方法中加上synchronized关键字才可以
 * (2)synchronized是jvm内置锁,当获取锁的线程执行完同步代码或者发生异常,jvm会释放锁,两个线程争抢锁的过程中,a获取锁阻塞了,其他线程一直等待,不可中断,非公平锁,可重入,假如不可重入,
* 那么1个类的synchornized方法不能调用本类其他synchornized方法,也不能调用父类中的synchornized方法 * lock锁是显示锁,锁可中断,也可设置锁的等待时长,获取锁后必须手动释放锁,可以是公平锁也可以是非公平锁
*/ public class SynchronizedDemo2 { public static void main(String[] args) { People p = new People(); CountDownLatch latch = new CountDownLatch(1); Thread a = new MyThread(p, 1,latch); Thread b = new MyThread(p, 2 , latch); a.start(); b.start(); latch.countDown(); } } class People { public synchronized void a() { for (int i = 0; i < 50; i++) { System.out.print("A"); try { Thread.sleep(5); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public synchronized void b() { for (int i = 0; i < 50; i++) { System.out.print("B"); try { Thread.sleep(5); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class MyThread extends Thread { People p; int c; CountDownLatch latch; MyThread(People p, int c ,CountDownLatch latch) { this.p = p; this.c = c; this.latch = latch; } @Override public void run() { try { latch.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (c == 1) p.a(); else if (c == 2) p.b(); } }

 

3线程不安全的例子

/**
 * 多个线程调用pass方法时,会对共享数据name和address发生修改,会造成数据不一致,线程不安全
 */
public class SynchronizedDemo3 {
    
    public static void main(String[] args) {
        Gate gate = new Gate();
        User bj = new User("Baobao", "Beijing", gate);
        User sh = new User("ShangLao", "ShangHai", gate);
        User gz = new User("GuangLao", "GuangZhou", gate);

        bj.start();
        sh.start();
        gz.start();
    }
}

class Gate {
    private int counter = 0;
    private String name = "Nobody";
    private String address = "Nowhere";

    public synchronized void pass(String name, String address) {
        this.counter++;
        this.name = name;
        this.address = address;
        verify();
    }

    private void verify() {
        if (this.name.charAt(0) != this.address.charAt(0)) {
            System.out.println("*******BROKEN********" + toString());
        }
    }

    public String toString() {
        return "No." + counter + ":" + name + "," + address;
    }
}

class User extends Thread {

    private final String myName;

    private final String myAddress;

    private final Gate gate;

    public User(String myName, String myAddress, Gate gate) {
        this.myName = myName;
        this.myAddress = myAddress;
        this.gate = gate;
    }

    @Override
    public void run() {
        System.out.println(myName + " BEGIN");
        while (true) {
            this.gate.pass(myName, myAddress);
        }
    }
}

 

posted @ 2019-10-29 14:10  踏月而来  阅读(1065)  评论(0编辑  收藏  举报