多线程同步基础

简介: 主线程执行完要等待其他线程执行完,才退出虚拟机主线程执行完需要让其他线程也结束,可设置为守护线程,守护线程必须在线程启动前开启实现方式和继承方式的区别:实现方式好处避免了但继承的局限性(不能继承其他类,只能继承Thread类)定义线程时,建议使用实现方式。两种方式区别:继承Thread:线程代码存放Thread子类的run方法中实现Runnable:线程代码存放接口子类


主线程执行完要等待其他线程执行完,才退出虚拟机



主线程执行完需要让其他线程也结束,可设置为守护线程,守护线程必须在线程启动前开启



实现方式和继承方式的区别:

实现方式好处避免了但继承的局限性(不能继承其他类,只能继承Thread类)

定义线程时,建议使用实现方式。

两种方式区别:

继承Thread:线程代码存放Thread子类的run方法中

实现Runnable:线程代码存放接口子类的run方法中


同步的前提:
1,必须要有两个或者两个以上的线程。
2,必须是多个线程使用同一个锁(同一个对象)。

必须保证同步中只能有一个线程在运行。


如何判断程序是否有安全问题:
1,明确哪些代码是多线程运行代码。
2,明确共享数据。
3,明确多线程运行代码中哪些语句是操作共享数据的。


同步的两种表现形式:同步代码块和同步函数

同步代码块


Object obj = new Object();

synchronized(obj)
            {
               //todo
            }


同步函数(使用的锁是this)

同步函数被静态修饰后使用的锁不再是this,因为静态方法中不可以有this,

静态的同步方法使用的锁是该方法所在类的字节码文件对象。 类名.class

public synchronized void add(int n)
    {
       
       
    }



    public static synchronized void show()
    {
        
    }

同步代码块和同步函数要使用同一把锁需要让同步代码块的锁设为this或者类名.class


多线程单例最好写成饿汉式(函数里面只有一句话)

class Single
{
    private static final Single s = new Single();
    private Single(){}
    public static Single getInstance()
    {
        return s;
    }
}


懒汉式的延时加载多线程访问时会出现安全问题,同步锁是该类的字节码对象

class Single
{
    private static Single s = null;
    private Single(){}


    public static  Single getInstance()
    {
        if(s==null)
        {
            synchronized(Single.class)
            {
                if(s==null)
                    //--->A;
                    s = new Single();
            }
        }
        return s;
    }
}





同步弊端死锁-同步嵌套,锁不一样

/*
死锁。
同步中嵌套同步。

*/

class Ticket implements Runnable
{
    private  int tick = 1000;
    Object obj = new Object();
    boolean flag = true;
    public  void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(obj)
                {
                    show();
                }
            }
        }
        else
            while(true)
                show();
    }
    public synchronized void show()//this
    {
        synchronized(obj)
        {
            if(tick>0)
            {
                try{Thread.sleep(10);}catch(Exception e){}
                System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
            }
        }
    }
}


class  DeadLockDemo
{
    public static void main(String[] args) 
    {

        Ticket t = new Ticket();

        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.start();
        try{Thread.sleep(10);}catch(Exception e){}
        t.flag = false;
        t2.start();


    }
}


class Test implements Runnable
{
    private boolean flag;
    Test(boolean flag)
    {
        this.flag = flag;
    }

    public void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(MyLock.locka)
                {
                    System.out.println(Thread.currentThread().getName()+"...if locka ");
                    synchronized(MyLock.lockb)
                    {
                        System.out.println(Thread.currentThread().getName()+"..if lockb");                    
                    }
                }
            }
        }
        else
        {
            while(true)
            {
                synchronized(MyLock.lockb)
                {
                    System.out.println(Thread.currentThread().getName()+"..else lockb");
                    synchronized(MyLock.locka)
                    {
                        System.out.println(Thread.currentThread().getName()+".....else locka");
                    }
                }
            }
        }
    }
}


class MyLock
{
    static Object locka = new Object();
    static Object lockb = new Object();
}

class  DeadLockTest
{
    public static void main(String[] args) 
    {
        Thread t1 = new Thread(new Test(true));
        Thread t2 = new Thread(new Test(false));
        t1.start();
        t2.start();
    }
}





本文出自 “点滴积累” 博客,请务必保留此出处http://tianxingzhe.blog.51cto.com/3390077/1699960

目录
相关文章
|
1天前
|
数据挖掘 调度 开发者
Python并发编程的艺术:掌握线程、进程与协程的同步技巧
并发编程在Python中涵盖线程、进程和协程,用于优化IO操作和响应速度。`threading`模块支持线程,`multiprocessing`处理进程,而`asyncio`则用于协程。线程通过Lock和Condition Objects同步,进程使用Queue和Pipe通信。协程利用异步事件循环避免上下文切换。了解并发模型及同步技术是提升Python应用性能的关键。
|
11天前
|
安全 Java 开发者
Java并发编程的艺术:解锁多线程同步的奥秘
本文将深入探讨Java并发编程的核心概念,揭示多线程环境下同步机制的工作原理与实践技巧。我们将从基础的synchronized关键字讲起,逐步过渡到高级的Lock接口和并发工具类,最后通过实例分析来加深理解。文章不仅旨在为初学者提供一个清晰的并发编程入门指南,同时也希望能够帮助有一定经验的开发者巩固和提升他们的并发处理能力。
|
21天前
|
安全 Java 开发者
深入理解Java中的多线程同步机制
深入理解Java中的多线程同步机制
28 1
|
25天前
|
安全 Java 容器
线程安全问题、同步代码块、同步方法、线程池详解
线程安全问题、同步代码块、同步方法、线程池详解
26 0
|
25天前
|
安全 Go 对象存储
C++多线程编程:并发与同步的实战应用
本文介绍了C++中的多线程编程,包括基础知识和实战应用。C++借助`<thread>`库支持多线程,通过`std::thread`创建线程执行任务。文章探讨了并发与同步的概念,如互斥锁(Mutex)用于保护共享资源,条件变量(Condition Variable)协调线程等待与通知,以及原子操作(Atomic Operations)保证线程安全。实战部分展示了如何使用多线程进行并发计算,利用`std::async`实现异步任务并获取结果。多线程编程能提高效率,但也需注意数据竞争和同步问题,以确保程序的正确性。
|
25天前
|
安全 Java 开发者
Java多线程同步方法
【5月更文挑战第24天】在 Java 中,多线程同步是保证多个线程安全访问共享资源的关键。Java 提供了几种机制来实现线程间的同步,保证了操作的原子性以及内存的可见性。
31 3
|
25天前
|
安全 Java 开发者
谈谈Java线程同步原理
【5月更文挑战第24天】Java 线程同步的原理主要基于两个核心概念:互斥(Mutual Exclusion)和可见性(Visibility)。
13 3
|
26天前
|
关系型数据库 MySQL Java
实时计算 Flink版产品使用合集之同步MySQL数据到Hologres时,配置线程池的大小该考虑哪些
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStreamAPI、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
27天前
|
安全 算法 Linux
【Linux 系统】多线程(线程控制、线程互斥与同步、互斥量与条件变量)-- 详解(下)
【Linux 系统】多线程(线程控制、线程互斥与同步、互斥量与条件变量)-- 详解(下)
|
27天前
|
存储 Linux 程序员
【Linux 系统】多线程(线程控制、线程互斥与同步、互斥量与条件变量)-- 详解(中)
【Linux 系统】多线程(线程控制、线程互斥与同步、互斥量与条件变量)-- 详解(中)

热门文章

最新文章