多线程编程核心技术-对象及变量的并发访问-synchronize同步方法(2)(下)

简介: 多线程编程核心技术-对象及变量的并发访问-synchronize同步方法(2)(下)

5).脏读


1dc618a0ed9580ce8bfa6facb208c08f.png

public class PublicVar {
    public String username = "A";
    public String password = "AA";
    synchronized public void setValue(String username, String  password){
        try {
            this.username = username;
            Thread.sleep(5000);
            this.password = password;
            System.out.println("setvValue method thread name= " + Thread.currentThread().getName() + " username="
                               + username + " password="+ password);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
    public void getValue(){
        System.out.println("getvValue method thread name= " + Thread.currentThread().getName() + " username="
                + username + " password="+ password);
    }
}


public class ThreadA extends Thread{
    private PublicVar publicVar;
    public ThreadA(PublicVar publicVar) {
        this.publicVar = publicVar;
    }
    @Override
    public void run() {
        super.run();
        publicVar.setValue("B","BB");
    }
}


public class Run {
    public static void main(String[] args) {
        try {
            PublicVar publicVar = new PublicVar();
            ThreadA thread = new ThreadA(publicVar);
            thread.start();
            Thread.sleep(200); //打印结果受此值大小影响
            publicVar.getValue();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}


synchronized public void getValue(){
        System.out.println("getvValue method thread name= " + Thread.currentThread().getName() + " username="
                + username + " password="+ password);
    }


5d4c6812c8535adbb050f4ddf2e1bce8.png

46a9d80a6e05e4e3b19d57a0ee70bcdf.png

不在出现脏读了!!

66ba272a0bfc97be54a5fa679e3d5482.png

1dc618a0ed9580ce8bfa6facb208c08f.png


6)synchronize锁重入


5d4c6812c8535adbb050f4ddf2e1bce8.png


a.类内方法间锁重入


public class Service {
    synchronized public void service1() {
        System.out.println("service1");
        service2();
    }
    synchronized public void service2() {
        System.out.println("service2");
        service3();
    }
    synchronized public void service3() {        
        System.out.println("service3");
    }
}


public class MyThread extends Thread{
    @Override
    public void run() {
        Service service = new Service();
        service.service1();
    }
}


public class Run {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();
    }
}


运行结果:

1dc618a0ed9580ce8bfa6facb208c08f.png

5d4c6812c8535adbb050f4ddf2e1bce8.png


b.父子类继承中也有可重入锁


public class Main {
    public int i =10;
    synchronized public void operateMainMethod(){
        try {
            i--;
            System.out.println("main print i=" + i);
            Thread.sleep(100);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}


public class Sub extends Main {
    synchronized public void operateSubMethod(){
        try {
            while (i>0){
                i--;
                System.out.println("sub print i="+i);
                Thread.sleep(100);
                this.operateMainMethod();
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}


public class MyThread extends Thread {
    @Override
    public void run() {
        Sub sub = new Sub();
        sub.operateSubMethod();
    }
}


public class Run {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
    }
}


运行结果:

1dc618a0ed9580ce8bfa6facb208c08f.png


7)出现异常,锁自动释放


public class Service {
    synchronized public void testMetdod(){
        if(Thread.currentThread().getName().equals("a")){
            System.out.println("ThreadName=" + Thread.currentThread().getName() + "" +
                    " run beginTime=" + System.currentTimeMillis());
            int i =1;
            while(i == 1){
                if(("" + Math.random()).substring(0,8).equals("0.123456")){
                    System.out.println("ThreadName="
                            + Thread.currentThread().getName()
                            + " run exceptionTime="
                            + System.currentTimeMillis());
                     Integer.parseInt("a");
                }else{
                    System.out.println("Thread B run Time="  +  System.currentTimeMillis());
                }
            }
        }
    }
}


public class ThreadA extends Thread {
    private Service service;
    public ThreadA(Service service) {
        this.service = service;
    }
    @Override
    public void run() {
        service.testMetdod();
    }
}


public class ThreadB extends Thread {
    private Service service;
    public ThreadB(Service service) {
        this.service = service;
    }
    @Override
    public void run() {
        super.run();
    }
}


public class Run {
    public static void main(String[] args) {
        try {
            Service service = new Service();
            ThreadA threadA = new ThreadA(service);
            threadA.setName("a");
            threadA.start();
            Thread.sleep(500);
            ThreadB b = new ThreadB(service);
            b.setName("b");
            b.start();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}


运行结果:

5d4c6812c8535adbb050f4ddf2e1bce8.png

46a9d80a6e05e4e3b19d57a0ee70bcdf.png


8)同步不具有继承性


public class Main {
    synchronized public void serviceMethod() {
        try {
            System.out.println("int main 下一步 sleep begin threadName=" + Thread.currentThread().getName()
                    + " time==" + System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("int main 下一步 sleep end threadName=" + Thread.currentThread().getName()
                    + " time==" + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


public class Sub extends Main {
    @Override
    public  void serviceMethod() {
        try {
            System.out.println("int sub 下一步 sleep begin threadName=" + Thread.currentThread().getName()
                    + " time==" + System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("int sub 下一步 sleep end threadName=" + Thread.currentThread().getName()
                    + " time==" + System.currentTimeMillis());
            super.serviceMethod();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}


public class MyThreadA extends Thread{
    private Sub sub;
    public MyThreadA(Sub sub) {
        this.sub = sub;
    }
    @Override
    public void run() {
        sub.serviceMethod();
    }
}


public class MyThreadB extends Thread{
    private Sub sub;
    public MyThreadB(Sub sub) {
        this.sub = sub;
    }
    @Override
    public void run() {
        sub.serviceMethod();
    }
}


public class Run {
    public static void main(String[] args) {
        try {
            Sub sub = new Sub();
            MyThreadA myThreadA = new MyThreadA(sub);
            myThreadA.setName("a");
            myThreadA.start();
            Thread.sleep(1000);
            MyThreadB myThreadB = new MyThreadB(sub);
            myThreadB.setName("b");
            myThreadB.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


运行结果:

1dc618a0ed9580ce8bfa6facb208c08f.png

说明:同步不能继承!!

修改子类为同步的方法。方法上加个同步关键字synchronize试试


public class Sub extends Main {
    @Override
     synchronized  public  void serviceMethod() {
        try {
            System.out.println("int sub 下一步 sleep begin threadName=" + Thread.currentThread().getName()
                    + " time==" + System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("int sub 下一步 sleep end threadName=" + Thread.currentThread().getName()
                    + " time==" + System.currentTimeMillis());
            super.serviceMethod();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}


运行结果:

5d4c6812c8535adbb050f4ddf2e1bce8.png

同步了。完美!!


相关文章
|
1月前
|
Java 调度
Java 线程同步的四种方式,最全详解,建议收藏!
本文详细解析了Java线程同步的四种方式:synchronized关键字、ReentrantLock、原子变量和ThreadLocal,通过实例代码和对比分析,帮助你深入理解线程同步机制。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Java 线程同步的四种方式,最全详解,建议收藏!
|
2月前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
47 1
|
2月前
|
安全 调度 C#
STA模型、同步上下文和多线程、异步调度
【10月更文挑战第19天】本文介绍了 STA 模型、同步上下文和多线程、异步调度的概念及其优缺点。STA 模型适用于单线程环境,确保资源访问的顺序性;同步上下文和多线程提高了程序的并发性和响应性,但增加了复杂性;异步调度提升了程序的响应性和资源利用率,但也带来了编程复杂性和错误处理的挑战。选择合适的模型需根据具体应用场景和需求进行权衡。
|
2月前
多线程通信和同步的方式有哪些?
【10月更文挑战第6天】
107 0
|
2月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
55 1
C++ 多线程之初识多线程
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
26 3
|
2月前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
22 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
35 2
|
2月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
41 1
|
2月前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
29 1