线程同步&线程池

线程同步

线程不同步会出现的问题:

  • 当多个线程操作同一资源时,会出现重复操作和和操作不存在的资源的问题,为了规避这一问题就需要线程的同步操作来实现资源的共同使用。

线程同步:

  • 当多个线程操作同一资源时,给操作该资源的代码加上一把锁,当有一个线程拿到这把锁后,其他线程都不能操作带锁的资源代码,直至拿到锁的线程释放锁。

线程同步实现的3种方式:

  • 同步代码块

    synchornized(obj){

    //涉及操作同一资源的代码

    }

    注: 没有静态的同步代码块

    obj: 任意类型的对象,相当于一把锁,操作同一资源的而线程必须使用同一把锁。

    如何保证多个线程使用同一把锁?

    在设置线程任务,即定义线程对象时在成员变量的位置上声明一个对象,将声明的变量放在sychornized代码块中

    /**

    *模拟买票功能,开启多个线程,同时买一百张票

    /

    public class SaleTicket implements Runnable{

    /


    不同对象使用同一个变量

    */

    private static int ticket=100 ;

        /**
    *不同线程使用同一个锁对象
    */
    private Object obj = new Object();
    @Override
    public void run() {
    while(true) {
    /**
    * 使用synchornized(obj) {} 代码块
    */
    synchronized (obj) {
    if (ticket > 0) {
    try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "sale=====" + ticket);
    ticket--;
    }
    }
    }
    }
    } public class SaleTicketDemoTest {
    public static void main(String[] args) {
    SaleTicket sale = new SaleTicket();
    //开启3个线程操作同一对象,从而操作同一资源
    Thread th1 = new Thread(sale);
    Thread th2 = new Thread(sale);
    Thread th3 = new Thread(sale);
    th1.start();
    th2.start();
    th3.start();
    }
    }
  • 同步方法

    public synchornied void 方法名(){

    //涉及操作同一资源的方法

    }

    同步方法的锁:

    同步方法的锁使用的是this对象,即new Thread(Xxx) 的Xxx对象

    package com.test.java;

    /**
    *模拟买票功能,开启多个线程,同时买一百张票
    */ public class SaleTicket implements Runnable{
    /*
    不同对象使用同一个变量
    */
    private static int ticket=100 ; /**
    *不同线程使用同一个锁对象
    */
    private Object obj = new Object();
    @Override
    public void run() {
    while(true) {
    saleTicket();
    }
    }
    /**
    * 定义个个同步方法 public snychonized void XXX(){}
    */
    public synchronized void saleTicket() {
    if (ticket > 0) {
    try {
    Thread.sleep(500); } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "sale=====" + ticket);
    ticket--;
    }
    }
    }

    静态的同步方法

    public static sychornized xxx(){

    //涉及操作共同资源的代码

    }

    静态同步方法的锁是类名.class对象

    package com.test.java;

    /**
    *模拟买票功能,开启多个线程,同时买一百张票
    */ public class SaleTicket implements Runnable{
    /*
    不同对象使用同一个变量
    */
    private static int ticket=100 ; /**
    *不同线程使用同一个锁对象
    */
    private Object obj = new Object();
    @Override
    public void run() {
    while(true) {
    saleTicket();
    } /**
    * 静态同步方法
    */ public static synchronized void saleTicket() {
    if (ticket > 0) {
    try {
    Thread.sleep(500); } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "sale=====" + ticket);
    ticket--;
    }
    }
    }
  • 锁机制

    Jdk1.5后在java.util.concurrent.locks

    lock的好处:解决了当共享资源的锁一直未被释放,其他线程无限等待的问题。

    当多个线程都只是进行读操作,所以当一个线程在进行读操作时,其他线程只能等待无法进行读操 作。因此就需要一种机制来使得多个线程都只是进行读操作时,线程之间不会发生冲突,通过Lock就可以办到

    Lock和synchornized的区别:

    1. Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这 个类可以实现同步访问;

      2. Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。

    lock的特点:

    1. 采用Lock,必须主动去释放锁,并且在发生异常时,不会自动释放锁。因此一般来说,使用Lock必须在try{}catch{}块中进行,并且将释放锁的操作放在finally块中进行,以保证锁一定被被释放,防止死锁的发生。通常使用Lock来进行同步的话

线程池

线程同步&线程池的更多相关文章

  1. 线程:主线程、子线程 同步线程、异步线程 单线程、多线程 System.Threading与System.Windows.Threading

    入门-------------------------------------------------------------------------------- 概述与概念    一个C#程序开始 ...

  2. Python并发编程-线程同步(线程安全)

    Python并发编程-线程同步(线程安全) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 线程同步,线程间协调,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直 ...

  3. Qt QThread 线程创建,线程同步,线程通信 实例

    1.  继承QThread, 实现run()方法, 即可创建线程. 2. 实例1 代码 myThread.h #ifndef MYTHREAD_H #define MYTHREAD_H #includ ...

  4. C#线程同步--线程通信

    问题抽象:当某个操作的执行必须依赖于另一个操作的完成时,需要有个机制来保证这种先后关系.线程通信方案:ManualResetEventSlim.ManualResetEvent.AutoResetEv ...

  5. 细说C#多线程那些事 - 线程同步和多线程优先级

    上个文章分享了一些多线程的一些基础的知识,今天我们继续学习. 一.Task类 上次我们说了线程池,线程池的QueueUserWorkItem()方法发起一次异步的线程执行很简单 但是该方法最大的问题是 ...

  6. C#并行编程(6):线程同步面面观

    理解线程同步 线程的数据访问 在并行(多线程)环境中,不可避免地会存在多个线程同时访问某个数据的情况.多个线程对共享数据的访问有下面3种情形: 多个线程同时读取数据: 单个线程更新数据,此时其他线程读 ...

  7. Linux多线程编程——多线程与线程同步

    多线程 使用多线程好处: 一.通过为每种事件类型的处理单独分配线程,可以简化处理异步事件的代码,线程处理事件可以采用同步编程模式,启闭异步编程模式简单 二.方便的通信和数据交换 由于进程之间具有独立的 ...

  8. java SE学习之线程同步(详细介绍)

           java程序中可以允许存在多个线程,但在处理多线程问题时,必须注意这样一个问题:               当两个或多个线程同时访问同一个变量,并且一些线程需要修改这个变量时,那么这个 ...

  9. Java之线程,常用方法,线程同步,死锁

    1, 线程的概念 进程与线程 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据 ...

随机推荐

  1. oracle计算两个时间的差值(XX天XX时XX分XX秒)

    在工作中需要计算两个时间的差值,结束时间 - 开始时间,又不想在js里写function,也不想在java里去计算,干脆就在数据库做了一个函数来计算两个时间的差值.格式为XX天XX时XX分XX秒: 上 ...

  2. 记录面试龙腾简合-java开发工程师经历

    /** * ############ * 变强是会掉光头发的!现在的头发还是很茂盛,是该开心还是难过呢.. * ############ * / 总结下近期面试龙腾简合-java开发岗的经历.附上笔试 ...

  3. 2017.12.21 学习vue的新得

    温故而知新,这句话说的真的有道理.每次回顾vue总会学到不一样的知识点,我就在想,我第一遍到底看了什么? 废话不多说,简要记录今天的所得: 1.v-if 与 v-show 同:都是条件渲染 异:渲染的 ...

  4. Nexus 离线更新中央仓库索引

    nexus可以在线更新中央仓库索引,但是更新速度慢,而且很有可能下载的索引不全.下面介绍一种离线更新中央仓库索引的方式,速度快并且可靠. 1.访问http://repo.maven.apache.or ...

  5. linux安装redis及外网访问

    1.下载Redis,最新版是redis-3.2.1.tar.gz 2.上传到Linux上,解压到/usr/local/下面  ,命令:tar -zxvf redis-3.2.1.tar.gz 3.我们 ...

  6. Android 禁止截屏、录屏 — 解决PopupWindow无法禁止录屏问题

    项目开发中,为了用户信息的安全,会有禁止页面被截屏.录屏的需求. 这类资料,在网上有很多,一般都是通过设置Activity的Flag解决,如: //禁止页面被截屏.录屏 getWindow().add ...

  7. python中@property装饰器的使用

    目录 python中@property装饰器的使用 1.引出问题 2.初步改善 3.使用@property 4.解析@property 5.总结 python中@property装饰器的使用 1.引出 ...

  8. Oracle 相关操作SQL

    SELECT l.session_id sid, s.serial#, l.locked_mode, l.oracle_username, s.user#,l.os_user_name,s.machi ...

  9. npm 学习笔记

    一.介绍 1.是什么 npm 全称是 Node Package Manager,即 Node 包管理工具. 但是发展到后来,并不仅是适用于 node.js 的包. 所以现在看 node_modules ...

  10. jieba分词基础知识

    安装:pip install jieba 导包:import jieba 精确模式:试图将句子最精确地切开,适合文本分析(很像人类一样去分词) jieba.cut(字符串) --> 返回生成器 ...