精华内容
下载资源
问答
  • 来回答前同事的一部分问题首先你要知道redis除了持久化,几乎所有操作都是在操作内存,比如像简单的set get操作都非常快,具体快我觉得你可以自己来做一个benchmark,并不难如果你关注新闻的话可以知道双11阿里的...

    来回答前同事的一部分问题

    首先你要知道redis除了持久化,几乎所有操作都是在操作内存,比如像简单的set get操作都非常快,具体多快我觉得你可以自己来做一个benchmark,并不难

    如果你关注新闻的话可以知道双11阿里的交易巅峰值是14w笔/s

    这基本已经是国内it界最高的并发了(那种几亿同时在线的不算),你再去想想操作内存的时间,不考虑事务,我只把14w条数据记下来看起来并不是什么难事对不对

    一台写不过来我十台总行了吧,所以除非你的set的value本身特别大,不用担心在操作时的等待时间,就算有1w个请求过来,你还是在操作内存,严格意义上说,redis本身应对的业务场景并不是一个高并发的场景,你看一下redis本身默认的连接数设置应该也就懂了

    应对这种场景,你用多线程+锁也没有什么问题(当然性能可能会差一点点),之前tim大神做过一个memcached和redis的性能对比,虽然年代久远,不过也可以说明一些问题,要知道memcached就是多线程+锁的模型,两者看起来差别也没有太过夸张。虽然结果是redis好一些。

    看到这里你是不是觉得单线程+io复用赢了?这可真不一定。。只是在这种场景下赢了而已,本身单线程io复用和多线程+锁其实只是两种编程模型,两种模型也都是为了解决问题,哪种优要看具体的业务场景,这里还是要说了,不服跑分啊

    go的goroutine本质是green threads,runtime来调度的用户态线程,其实这种概念在其他语言里也有,只是其他语言都是以第三方库来做这件事情,go把它集成在了语言内,并且不用你自己去管理调度的事情,go语言里的实现只是让你可以更方便地写而已,所以这东西并不是银弹,不用太过迷信,go所带来的更重要的是开发效率的提升,并没有解决什么具体的问题。

    关于epoll,go语言的net库底层也是用epoll来做io复用的(仅指linux平台),epoll这个东西只是linux下的一种io复用的实现,在其他的发行版里还有其他变种,而程序员们其实不太想关心你这些事情,他们希望在linux下写的程序去freebsd还能跑,所以libevent棒棒哒,当然你写go的话,这些事情不用操心。

    展开全文
  • 1.java多线程加锁是对谁加锁?答:当然是对共享资源加锁啊,对谁进行访问修改,就对象进行加锁。以便使多线程按序访问此共享对象比如:在具体的Java代码中需要完成一下两个操作:把竞争访问的资源类Foo变量x标识为...

    1.java多线程加锁是对谁加锁?

    答:当然是对共享资源加锁啊,对谁进行访问修改,就对象进行加锁。以便使多线程按序访问此共享对象

    比如:

    在具体的Java代码中需要完成一下两个操作:

    把竞争访问的资源类Foo变量x标识为private;

    同步哪些修改变量的代码,使用synchronized关键字同步方法或代码。

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    package cn.thread;

    public class Foo2 {

    private int x = 100;

    public int getX() {

    return x;

    }

    //同步方法

    public synchronized int fix(int y) {

    x = x - y;

    System.out.println("线程"+Thread.currentThread().getName() + "运行结束,减少“" + y

    + "”,当前值为:" + x);

    return x;

    }

    // //同步代码块

    // public int fix(int y) {

    // synchronized (this) {

    // x = x - y;

    // System.out.println("线程"+Thread.currentThread().getName() + "运行结束,减少“" + y

    // + "”,当前值为:" + x);

    // }

    //

    // return x;

    // }

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    package cn.thread;

    public class MyRunnable2 {

    public static void main(String[] args) {

    MyRunnable2 run = new MyRunnable2();

    Foo2 foo2=new Foo2();

    MyThread t1 = run.new MyThread("线程A", foo2, 10);

    MyThread t2 = run.new MyThread("线程B", foo2, -2);

    MyThread t3 = run.new MyThread("线程C", foo2, -3);

    MyThread t4 = run.new MyThread("线程D", foo2, 5);

    t1.start();

    t2.start();

    t3.start();

    t4.start();

    }

    class MyThread extends Thread {

    private Foo2 foo2;

    /**当前值*/

    private int y = 0;

    MyThread(String name, Foo2 foo2, int y) {

    super(name);

    this.foo2 = foo2;

    this.y = y;

    }

    public void run() {

    foo2.fix(y);

    }

    }

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    线程线程A运行结束,减少“10”,当前值为:90

    线程线程C运行结束,减少“-3”,当前值为:93

    线程线程B运行结束,减少“-2”,当前值为:95

    线程线程D运行结束,减少“5”,当前值为:90

    比如:

    对于同步,除了同步方法外,还可以使用同步代码块,有时候同步代码块会带来比同步方法更好的效果。

    追其同步的根本的目的,是控制竞争资源的正确的访问,因此只要在访问竞争资源的时候保证同一时刻只能一个线程访问即可,因此Java引入了同步代码快的策略,以提高性能。

    在上个例子的基础上,对oper方法做了改动,由同步方法改为同步代码块模式,程序的执行逻辑并没有问题。

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    package cn.thread;

    /**

    * 线程同步方法

    *

    * @author 林计钦

    * @version 1.0 2013-7-24 上午10:12:47

    */

    public class ThreadSynchronizedCode {

    public static void main(String[] args) {

    ThreadSynchronizedCode t = new ThreadSynchronizedCode();

    User u = t.new User("张三", 100);

    MyThread t1 = t.new MyThread("线程A", u, 20);

    MyThread t2 = t.new MyThread("线程B", u, -60);

    MyThread t3 = t.new MyThread("线程C", u, -80);

    MyThread t4 = t.new MyThread("线程D", u, -30);

    MyThread t5 = t.new MyThread("线程E", u, 32);

    MyThread t6 = t.new MyThread("线程F", u, 21);

    t1.start();

    t2.start();

    t3.start();

    t4.start();

    t5.start();

    t6.start();

    }

    class MyThread extends Thread {

    private User u;

    /**存款金额*/

    private int y = 0;

    MyThread(String name, User u, int y) {

    super(name);

    this.u = u;

    this.y = y;

    }

    public void run() {

    u.oper(y);

    }

    }

    class User {

    /** 账号 */

    private String code;

    /** 余额 */

    private int cash;

    User(String code, int cash) {

    this.code = code;

    this.cash = cash;

    }

    public String getCode() {

    return code;

    }

    public void setCode(String code) {

    this.code = code;

    }

    /**

    * 存款

    *

    * @param x 欲存款金额

    *

    */

    public void oper(int x) {

    try {

    Thread.sleep(10L);

    synchronized (this) {

    this.cash += x;

    System.out.println("线程" + Thread.currentThread().getName() + "运行结束,增加“" + x

    + "”,当前用户账户余额为:" + cash);

    }

    Thread.sleep(10L);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    @Override

    public String toString() {

    return "User{" + "code='" + code + '\'' + ", cash=" + cash + '}';

    }

    }

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    线程线程B运行结束,增加“-60”,当前用户账户余额为:40

    线程线程A运行结束,增加“20”,当前用户账户余额为:60

    线程线程C运行结束,增加“-80”,当前用户账户余额为:-20

    线程线程D运行结束,增加“-30”,当前用户账户余额为:-50

    线程线程F运行结束,增加“21”,当前用户账户余额为:-29

    线程线程E运行结束,增加“32”,当前用户账户余额为:3

    展开全文
  • 这时候就需要对修改操作进行加锁,让jvm里同一时刻只能有一个线程能够执行修改方法。下面是一个未加锁的修改方法:publicvoidupdate(Entryentry){dao.update(entry);}现在讨论下传统的加锁方法。我们知道每一个...

    当对数据修改时,如果两个线程同时去修改同一条数据,这样产生的结果就不是我们预期的结果。这时候就需要对修改操作进行加锁,让jvm里同一时刻只能有一个线程能够执行修改方法。

    下面是一个未加锁的修改方法:

    public void update(Entry entry){

    dao.update(entry);

    现在讨论下传统的加锁方法。我们知道每一个对象都隐含了一个锁,那就是对象本身。我们可以在方法体上加上同步字段synchronized

    public synchronized void update(Entry entry){

    dao.update(entry);

    但如果方法里代码很多,那么加在方法上会锁住很多代码,我们可以使用同步块

    public void update(Entry entry){

    dobefore();

    synchronized(this){

    dao.update(entry);

    doend();

    而需要注意的是如果一个类中存在多个同步方法,那么所有同步方法的锁都是对象本身,也就是说当执行update的时候,别的线程不仅不能执行update连类中别的同步方法也不能使用。当然也可以使用一点技巧去规避这个问题,比如使用其他锁。

    我们这篇博客说得不是上面的方法,而是另外一个位于java.util.concurrent.locks包下的ReentrantLock。

    官方是这么说的:

    一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

    ReentrantLock 将由最近成功获得锁,并且还没有释放该锁的线程所拥有。当锁没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁并返回。如果当前线程已经拥有该锁,此方法将立即返回。可以使用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此情况是否发生。

    此类的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间最长的线程。否则此锁将无法保证任何特定访问顺序。与采用默认设置(使用不公平锁)相比,使用公平锁的程序在许多线程访问时表现为很低的总体吞吐量(即速度很慢,常常极其慢),但是在获得锁和保证锁分配的均衡性时差异较小。不过要注意的是,公平锁不能保证线程调度的公平性。因此,使用公平锁的众多线程中的一员可能获得多倍的成功机会,这种情况发生在其他活动线程没有被处理并且目前并未持有锁时。还要注意的是,未定时的 tryLock 方法并没有使用公平设置。因为即使其他线程正在等待,只要该锁是可用的,此方法就可以获得成功。

    使用它也很简单,你可以用如下结构来使用他:

    class X {

    private final ReentrantLock lock = new ReentrantLock();

    // ...

    public void m() {

    lock.lock();  // block until condition holds

    try {

    // ... method body

    } finally {

    lock.unlock()

    }

    }

    }

    常用的方法就如上面所说的一样,lock和unlock

    lock

    public void lock()

    获取锁。

    如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为 1。

    如果当前线程已经保持该锁,则将保持计数加 1,并且该方法立即返回。

    如果该锁被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态,此时锁保持计数被设置为 1。

    指定者:

    接口 Lock 中的

    lock

    unlock

    public void unlock()

    试图释放此锁。

    如果当前线程是此锁所有者,则将保持计数减 1。如果保持计数现在为 0,则释放该锁。如果当前线程不是此锁的持有者,则抛出 IllegalMonitorStateException。

    指定者:

    接口 Lock 中的

    unlock

    抛出:

    IllegalMonitorStateException - 如果当前线程没有保持此锁

    当然他还有别的很多方法,需要的话可以自己去看看。

    对比synchronized这个锁是独立的,在一个类中多个同步块之间都是独立的,互不影响。最后说一句,因为同步块会让一段代码同一时刻只能有一个线程使用,多线程同时访问,一个使用其他都是等待状态,那么就存在一个性能问题。如果理解原子性,又那么牛X,利用原子性写出避免同步的免锁代码,什么synchronized啊,ReentrantLock啊,都是浮云。

    展开全文
  • Java 多线程加锁

    2021-03-06 13:17:11
    以前的同步操作 基本上都是用到 synchronised 关键字,类似代码如下:synchronised(obj){//dosomething...}来做到同步,在 JDK5.0 里面有这么一个对象,ReentrantLock,发觉她的加锁编程的方式非常的适合日常的加锁...

    以前的同步操作 基本上都是用到 synchronised 关键字,类似代码如下:

    synchronised(obj){

    //dosomething...

    }来做到同步,

    在 JDK5.0  里面有这么一个对象,ReentrantLock,发觉她的加锁编程的方式非常的适合日常的加锁习惯,

    EG:

    package com.thread.synchronise;

    import java.util.concurrent.locks.ReentrantLock;

    public class SynchroTest extends Thread{

    private int count = 0;

    private final ReentrantLock lock = new ReentrantLock();

    public void run()

    {

    //这里加了几次锁,在后面就的要相应的解锁 几次lock.lock();  // block until condition holds      try {

    count++;

    System.out.println(" count = "+count);

    try {

    Thread.sleep(3000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println(" count = "+count);

    } finally {lock.unlock();      }

    }

    /**

    * @param args

    */

    public static void main(String[] args) {

    // TODO Auto-generated method stub

    SynchroTest st1 = new SynchroTest();

    //  SynchroTest st2 = new SynchroTest();

    //  SynchroTest st3 = new SynchroTest();

    //这里不能够调用   new Thread(st1).run();方法,否则就不是多线程的了

    new Thread(st1).start();

    new Thread(st1).start();

    new Thread(st1).start();

    }

    }

    如果该线程等待某暂时获取不到的资源,那么我们可以用Condition Object来避免死锁情况。

    sufficientFunds = lock.newCondition();

    如果条件不满足:

    sufficientFunds.await();

    这时线程就会释放锁并进入blocked状态,其他线程就有机会执行操作。当其他线程执行完后,就可通知等待的线程继续执行它的操作了:

    sufficientFunds.signalAll();

    展开全文
  • C++ 多线程加锁

    2021-08-13 16:00:36
    unique_lock加锁的方式 std::unique_lock 与std::lock_guard用法一样,但是std::unique_lock 更牛逼一点,但是缺点就是稍微慢一点,内存用的稍微一点。 介意以上两单自行切换成std::lock_guard 用法很简单 ...
  • 多线程 加锁

    2021-09-24 10:46:27
    多线程来说,资源是共享的,基本上不存在不允许访问的情况,但是,共享的资源在某一时间点只能有一个线程占用,所以需要给资源加锁。 线程的锁的种类 互斥锁 读写锁 条件变量 自旋锁 信号灯 互斥锁 互斥锁...
  • Java codepublic class MyThread extends Thread{ private CountDownLatch threadsSignal; private int hsmapCapacity; private long forAndVal; private boolean DNAFormat; pr...
  • 线程的背景知识、创建线程、 交替获得CPU时间片、多线程抢夺同一个变量、线程 加锁、解锁机制
  • 看到这个题目我的第一想法就是这是一个多线程的问题,有两个线程同时操作同一个资源,这时候就是java多线程中最常见的同步问题了。因为线程的开始是cpu决定的,所以我们无法控制线程的创建时间与创建顺序。下面贴上...
  • 多线程加锁并发任务

    2021-01-14 21:26:10
    # coding=utf-8import threadingimport timeimport stringimport randomclass TestTreading(threading.Thread):def __init__(self,func):threading.Thread.__init__(self)self.func =func#@overridedef run(self):mu...
  • 有锁才能运行. 当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。每次只有一个线程可以获得锁。...线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)...
  • Java多线程加锁例子

    2021-09-15 01:09:41
    Java多线程加锁例子一、错误示例二、正确示例 一、错误示例 static int a = 0; //多线程同时操作 val a @Test public void test4() throws InterruptedException { Runnable runnable = () -> { ...
  • 1、加锁不正确导致数据不一致:m1执行过程中,m2(未加synchronized)可以执行,因为m2不用获得锁就可以执行1 public class TT implementsRunnable {2 int b = 100;34 public synchronized void m1() throwsException ...
  • 但如果想在servlet中添加更的状态,那么是否只需添加更线程安全状态变量就足够了?假设我们希望提升servlet的性能:将最近的计算结果缓存起来,当两个连续的请求对相同的数值进行因数分解时,可以直接使用上一...
  • 加锁的实现简易版直接加锁无判断来同步类的创建public class Singleton0{private Singleton0(){}private static Singleton0 instance;public static Singleton0 getInstance(){synchronized (Singleton0.class){if ...
  • 当A线程访问一个object的时候,首先会获取该对象的对象锁,然后访问锁定的代码,而B线程访问一个对象object顶的代码区时,因为线程A之前获取到对象object的对象锁,因此线程B访问同步代码区的时候会被阻塞,直到...
  • QT 多线程程序之可重入与线程安全 是本节要介绍的内容,继续着 解析 QT 多线程程序详细设计 上篇 ,开始介绍。先来看内容。在Qt文档中,术语“可重入”与“线程安全”被用来说明一个函数如何用于多线程程序。假如一...
  • 在我们这批新人转正评审的时候,我师父问了我的小伙伴一个问题:为什么一些更新界面的方法只能在主线程中调用?师父没有问我这个问题,让知其然但不知其所以然的我有种侥幸逃过一难的心情。...多线程不是更好吗?带...
  • 一、线程的基本概念1.1 单线程简单的说,单线程就是进程中只有一个线程。单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。Java示例:public class SingleThread {public ...
  • 原标题:Android 最佳并发实践之线程篇在上一篇文章中,我们简要地了解了下 Android ...线程状态线程作为 CPU 最小的执行单元,通常情况下的 Android 并发是指多线程环境下进行并发,那么我们首先了解下线程。CPU 负...
  • QT[3]多线程

    千次阅读 2021-01-17 16:07:41
    Qt线程类Qt包含下面一些线程相关的类:QThread提供了开始一个新线程的方法QThreadStorage提供逐线程数据存储QMutex提供相互排斥的锁,或互斥量QMutexLocker是一个便利类,它可以自动对QMutex加锁与解锁...
  • 为什么三线程加锁比三线程加锁还慢呢?当两个线程写入同一个 cache 的不同部分时,会互相竞争该 cache 行,也就是写后写的问题。下文会详细分析。为什么三线程加锁Cache32比三线程加锁Cache32比慢几乎一倍呢?其...
  • 读写锁也是线程同步中的一种同步机制,简单的来说:读写锁既有读的方面也有写的方面,其中读是共享锁,而写是独占锁,而且系统中读写锁的分配是写锁优先的。下面的用例,证明了读锁是共享锁。#include#include#...
  • 为了测试java多线程死锁得到java多线程死锁的直观感觉,写出以下测试代码。public class TestDeadLock{public static void main(String[] args){A a=new A();B b=new B(a);a.set(b);Thread t1=new Thread(a);Thread ...
  • 学习多线程,大家总是说锁怎么样,怎么样,加什么锁,什么时候加,什么时候释放,那么大家有没有想过锁锁住的是哪些东西我们知道 synchronized、ReentrantLock 这些锁手段,synchronized 使用的是对象锁,类锁,...
  • linux多线程读写锁类

    2021-05-15 13:43:30
    基于linux的posix多线程读写锁的头文件ThreadReadWriteLock.h#ifndefThreadReadWriteLock.class#defineThreadReadWriteLock.class#includeclassThreadReadWriteLock{public:ThreadReadWriteLock();~...
  • 以下代码为不加锁的时候的代码,毫无疑问是乱序的,因为两个线程同时操作了全局变量 #include <thread> #include <iostream> #include <mutex> #include <list> // 全局变量 std::mutex my_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 234,350
精华内容 93,740
关键字:

多线程加锁