多线程 - 同步

进程:正在执行的程序。

线程:是进程中用于控制程序执行的控制单元(执行路径,执行情景)

进程中至少有一个线程。

对于JVM,启动时,只好有两个线程:jvm的主线程。jvm的垃圾回收线程。

如何在程序中自定义线程呢?

Java给我们提供了对象线程这类事物的描述。该类是Thread

该类中定义了,
创建线程对象的方法(构造函数).
提供了要被线程执行的代码存储的位置(run())

还定义了开启线程运行的方法(start()).
同时还有一些其他的方法用于操作线程:
static Thread currentThead():
String getName():
static void sleep(time)throws InterruptedException:

要运行的代码都是后期定义的。
所以创建线程的第一种方式是:继承Thread类。原因:要覆盖run方法,定义线程要运行的代码。

步骤:
1,继承Thread类。
2,覆盖run方法。将线程要运行的代码定义其中。
3,创建Thread类的子类对象,其实就是在创建线程,调用start方法。

如果自定义的类中有多线程要运行的代码。但是该类有自己的父类。
那么就不可以在继承Thread。怎么办呢?

Java给我们提供了一个规则。Runnable接口。
如果自定义类不继承Thread,也可以实现Runnable接口。并将多线程要运行的代码存放在Runnable的run方法中。
这样多线程也可以帮助该类运行。
这样的操作有一个好处:避免了单继承的局限性。

创建线程的第二种方式:实现Runnable接口。

步骤:
1,定义了实现Runnable接口。
2,覆盖接口的run方法。将多线程要运行的代码存入其中。
3,创建Thread类的对象(创建线程),并将Runnable接口的子类对象作为参数传递给Thread的构造函数。
为什么要传递?因为线程要运行的代码都在Runnable子类的run方法中存储。所以要将该run方法所属的对象
传递给Thread。让Thread线程去使用该对象调用其run方法。
4,调用Thread对象的start方法。开启线程。

动手写代码。

两种方式的特点:
实现方式,因为避免了单继承的局限性,所以创建线程建议使用第二种方式。

#

第一重点:创建线程的两种方式

#

作为了解:
线程的状态。
1,被创建。
2,运行。
3,冻结。
4,消亡。

其实还有一种特殊的状态:临时状态。

该临时状态的特点:
具备了执行资格,但不具备执行权。

冻结状态的特点:
放弃了执行资格。

多线程具备随机性。因为是由cpu不断的快速切换造成的。

就有可能会产生多线程的安全问题。

问题的产生的原因:
几个关键点:
1,多线程代码中有操作共享数据。
2,多条语句操作该共享数据。

当具备两个关键点时,
有一个线程对多条操作共享数据的代码执行的一部分。还没有执行完,另一个线程开始参与执行。
就会发生数据错误。

解决方法:
当一个线程在执行多条操作共享数据代码时,其他线程即使获取了执行权,也不可以参与操作。

Java就对这种解决方式提供了专业的代码。
同步
同步的原理:就是将部分操作功能数据的代码进行加锁。

示例:火车上的卫生间。

同步的表现形式:
1,同步代码块。
2,同步函数。
两者有什么不同:
同步代码块使用的锁是任意对象。
同步函数使用的锁是this。

注意:对于static的同步函数,使用的锁不是this。是 类名.class 是该类的字节码文件对象。
涉及到了单例设计模式的懒汉式。

同步的好处:解决了线程的安全问题。

弊端:
较为消耗资源。
同步嵌套后,容易死锁。

要记住:同步使用的前提:
1,必须是两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。
这是才可以称为这些线程被同步了。

死锁代码一定会写。但开发时一定注意避免。

#

第二重点:同步的所有特性

#
/*

class Thread 
{
    private Runnable target;

    Thread()
    {
    }
    Thread(Runnable target)
    {
        this.target = target;
    }

    public void run()
    {
        if(target!=null)
            target.run();
    }
}

class Test implements Runnable
{
    public void run()
    {}
}


main()
{
    Test q = new Test();
    Thread t = new Thread(q);
}


class Demo extends Thread
{
    public void run()
    {
    }
}
class  
{
    public static void main(String[] args) 
    {
        System.out.println("Hello World!");
    }
}
*/
### 回答1: 多线程中的同步访问是指多个线程同时访问共享资源时,需要通过一定的机制来保证数据的正确性和一致性。常见的同步访问机制包括锁、信号量、条件变量等。在Java中,可以使用synchronized关键字来实现同步访问,也可以使用Lock接口及其实现类来实现。同步访问的目的是避免多个线程同时修改同一个共享资源,从而导致数据不一致或者程序出现异常。 ### 回答2: 多线程是一种被广泛应用的编程技术,其可以使用多个线程同时执行不同的任务,以提高程序的运行效率和响应速度。但同时使用多个线程也会带来一些问题,其中之一就是线程之间的同步访问问题。本文将从同步访问的概念、线程安全、同步方式等方面介绍多线程同步访问问题。 一、同步访问的概念 多线程中的同步访问是指多个线程在访问共享资源时,为了避免竞争条件和数据不一致问题,需要进行协调和同步。例如,多个线程同时访问同一个对象中的方法或属性,就需要进行同步处理,避免出现数据不一致或错乱的情况。 二、线程安全 线程安全是指在多线程环境中,一个对象能够保证经过多个线程访问后仍能保持其状态和正确性。线程安全的实现需要考虑以下两个方面: 1、互斥访问:互斥访问指的是,在某个线程访问对象时,其他线程不能同时访问该对象,需要进行排队等待。 2、共享对象的状态安全:共享对象的状态安全指的是,共享对象在多个线程中被访问时,能够保持其状态的一致性,避免出现数据不一致或错乱的情况。 三、同步方式 实现多线程同步访问可以使用以下方式: 1、同步方法:将需要同步访问的代码块封装在一个 synchronized 修饰的方法中,保证在任意时刻最多只有一个线程执行该代码块。但是需要注意,同步方法会影响程序的执行效率,因为其他线程必须等待当前线程执行完毕后才能执行。 2、同步块:使用 synchronized 关键字和任意对象实现同步块。同步块将需要同步访问的代码块括到 synchronized 关键字指定的对象中,保证在任意时刻最多只有一个线程执行该代码块。与同步方法相比,同步块的粒度更细,执行效率也更高。 3、Lock 锁:Lock 锁是 java.util.concurrent.locks 包中提供的一种线程锁,通过 Lock 的 lock() 和 unlock() 方法实现同步访问。与 synchronized 关键字相比,Lock 锁具有更灵活、更可靠的特性,如可重入、可中断、timeout 等。但是需要注意,使用 Lock 锁时必须手动释放锁,否则会导致死锁等问题。 四、总结 多线程同步访问是提高程序运行效率和响应速度的必要手段,同时也是保障程序正确性和安全性的重要措施。在实现多线程同步访问时,需要考虑互斥访问和共享对象的状态安全问题,并选择合适的同步方式,如同步方法、同步块和 Lock 锁等。通过合理的同步处理,可以避免出现数据不一致或错乱的情况,提高程序的稳定性和可靠性。 ### 回答3: 在Java编程中,多线程是一项非常重要的概念。Java提供了各种各样的线程操作,可以使程序员更自由地控制线程的执行。在使用多线程的过程中,同步访问是一项非常核心的技术,它能够帮助程序员解决线程并发访问时可能引发的各种问题。 多线程可能涉及到多个线程对同一资源的操作,例如内存或是磁盘文件。如果多个线程同时访问同一个资源,就可能导致数据的不一致性、竞争条件和死锁等问题。解决这类问题的一种方法就是同步访问。 同步访问的原理是在多个线程使用同一个资源的时候,使用锁机制来保证各个线程对资源的访问顺序,确保数据一致性。Java中提供了关键字synchronized来实现同步访问,这个关键字可以应用于方法和代码块。 通过使用synchronized,我们可以使多个线程在访问同一对象时有序地执行,从而避免竞争条件的产生。在使用synchronized时,要注意一些细节,例如避免死锁,确保锁的粒度正确等。 另外,Java的并发包中提供了各种各样的同步访问机制,例如ReentrantLock、Semaphore、CountDownLatch等等。这些机制可以更加灵活地控制线程的访问,使多线程编程更加方便和安全。 总之,同步访问是多线程编程中非常重要的一个概念。通过使用同步访问,我们可以保证多个线程对同一资源的访问有序地进行,从而避免竞争条件和死锁等问题。在Java中,我们可以使用synchronized关键字或是并发包中的各种机制来实现同步访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值