多线程编程核心技术-对象及变量的并发访问-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多线程编程的陷阱与最佳实践####
【10月更文挑战第29天】 本文深入探讨了Java多线程编程中的常见陷阱,如竞态条件、死锁、内存一致性错误等,并通过实例分析揭示了这些陷阱的成因。同时,文章也分享了一系列最佳实践,包括使用volatile关键字、原子类、线程安全集合以及并发框架(如java.util.concurrent包下的工具类),帮助开发者有效避免多线程编程中的问题,提升应用的稳定性和性能。 ####
15 1
|
4天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####
|
5天前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
30 4
|
1月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
38 1
C++ 多线程之初识多线程
|
15天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
13 3
|
15天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
12 2
|
15天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
27 2
|
15天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
26 1
|
15天前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
26 1
|
15天前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
21 1