JDK рд╕рдорд╡рд░реНрддреА рдкреИрдХреЗрдЬ

рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЬрд╛рд╡рд╛ рдореЗрдВ рдореМрдЬреВрдж рдореЗрдореЛрд░реА рдореЙрдбрд▓ рдЗрд╕ рдХреЛрдб рдореЗрдВ рдереНрд░реЗрдб рд░реЗрд╕рд┐рдВрдЧ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рдХреЛрдб рдХреЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдирд┐рд╖реНрдкрд╛рджрди рдЖрджреЗрд╢ рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИред рдФрд░ рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рд░реЗрд╕рд┐рдВрдЧ рд╕реЗ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдирдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдФрд░ рдПрдХреНрд╕рдЪреЗрдВрдЬ рдХрд░рдиреЗ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

HotSpot JDK рдХреЗ рд╕рд╛рде рд╢рд╛рдорд┐рд▓ java.util.concurrent рдкреИрдХреЗрдЬ рдореЗрдВ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЯреВрд▓ рджрд┐рдП рдЧрдП рд╣реИрдВ:


рдкрд░рдорд╛рдгреБ

java.util.concurrent.atomic рдЪрд╛рдЗрд▓реНрдб рдкреИрдХреЗрдЬ рдореЗрдВ рдЖрджрд┐рдо рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдкрд░рдорд╛рдгреБ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИред рдЗрди рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдЕрдиреБрдмрдВрдз "рдкреНрд░реЛрд╕реЗрд╕рд░ рд╕рдордп рдХреА 1 рдЗрдХрд╛рдИ" рдХреЗ рд▓рд┐рдП compare-and-set рдСрдкрд░реЗрд╢рди рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдЪрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдорд╛рди рд╕реЗрдЯ рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдЗрд╕рдХреЗ рдкреБрд░рд╛рдиреЗ рдореВрд▓реНрдп (рдЖрд╢рд╛рд╡рд╛рджреА рд▓реЙрдХрд┐рдВрдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг) рдХреЛ рднреА рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐, рдЬрд┐рд╕ рдХреНрд╖рдг рд╕реЗ рд╡рд┐рдзрд┐ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЪрд░ рдХрд╛ рдорд╛рди рдЕрдкреЗрдХреНрд╖рд┐рдд рд╕реЗ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдкрд░рд┐рдгрд╛рдо false рд╣реЛрдЧрд╛ред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, long рдЪрд░ [1,2,3,4,5] рдФрд░ [-1,-2,-3,-4,-5] ред рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рд╕рд░рдгреА рдкрд░ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╣реЛрдЧрд╛ рдФрд░ рддрддреНрд╡реЛрдВ рдХреЛ рдПрдХ рдПрдХрд▓ рдЪрд░ рдореЗрдВ рд╕рд╛рд░рд╛рдВрд╢рд┐рдд рдХрд░реЗрдЧрд╛ред рдПрдХ рдирд┐рд░рд╛рд╢рд╛рд╡рд╛рджреА рддрд╛рд▓рд╛ рдХреЗ рд╕рд╛рде рдХреЛрдб ( рдЧреНрд░реВрд╡реА ) рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 class Sum { static monitor = new Object() static volatile long sum = 0 } class Summer implements Callable { long[] data Object call() throws Exception { data.each { synchronized (Sum.monitor) { println("${Thread.currentThread().name}: add ${it} to ${Sum.sum}") Sum.sum += it } } } } Executors.newFixedThreadPool(2).invokeAll([ new Summer(data: [1,2,3,4,5]), new Summer(data: [-1,-2,-3,-4,-5]) ]) print("Sum: ${Sum.sum}") 


рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреА рдЙрдореНрдореАрдж рдХреА рдЬрд╛рдПрдЧреА:

 pool-1-thread-1: add 1 to 0 pool-1-thread-2: add -1 to 1 pool-1-thread-1: add 2 to 0 pool-1-thread-2: add -2 to 2 pool-1-thread-1: add 3 to 0 pool-1-thread-2: add -3 to 3 pool-1-thread-1: add 4 to 0 pool-1-thread-1: add 5 to 4 pool-1-thread-2: add -4 to 9 pool-1-thread-2: add -5 to 5 Sum: 0 


рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреНрд░рджрд░реНрд╢рди рдиреБрдХрд╕рд╛рди рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЕрдзрд┐рдХ рдмреЗрдХрд╛рд░ рдХрд╛рдо рд╣рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрд╕рд╛рдзрди рд▓реЗрддрд╛ рд╣реИ:


рдПрдХ рд╣реА рд░рд╛рд╢рд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╕рдордп рдЖрд╢рд╛рд╡рд╛рджреА рд▓реЙрдХрд┐рдВрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП AtomicLong рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

 class Sum { static volatile AtomicLong sum = new AtomicLong(0) } class Summer implements Callable { long[] data Object call() throws Exception { data.each { while(true) { long localSum = Sum.sum.get() if (Sum.sum.compareAndSet(localSum, localSum + it)) { println("${Thread.currentThread().name}: add ${it} to ${Sum.sum}") break; } else { println("[MISS!] ${Thread.currentThread().name}: add ${it} to ${Sum.sum}") } } } } } Executors.newFixedThreadPool(2).invokeAll([ new Summer(data: [1,2,3,4,5]), new Summer(data: [-1,-2,-3,-4,-5]) ]) print("Sum: ${Sum.sum}") 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк "рдЧрд▓рдд" рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрддрдиреЗ рд╕рд╛рд░реЗ рдирд╣реАрдВ рдереЗ:

 [MISS!] pool-1-thread-1: add 1 to -1 pool-1-thread-2: add -1 to -1 pool-1-thread-2: add -2 to -3 [MISS!] pool-1-thread-1: add 1 to -3 pool-1-thread-2: add -3 to -6 pool-1-thread-1: add 1 to -5 [MISS!] pool-1-thread-2: add -4 to -5 pool-1-thread-1: add 2 to -7 pool-1-thread-2: add -4 to -7 pool-1-thread-1: add 3 to -9 pool-1-thread-2: add -5 to -9 pool-1-thread-1: add 4 to -5 pool-1-thread-1: add 5 to 0 Sum: 0 


рдЬрдм рдЖрд╢рд╛рд╡рд╛рджреА рд▓реЙрдХрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рдЪрд░ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрд░рд╡рд╛рдИ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рди рд▓рдЧреЗред рдпрд╣ рдХреНрд░рд┐рдпрд╛ рдЬрд┐рддрдиреА рд▓рдВрдмреА рд╣реЛрдЧреА, рдЙрддрдиреА рдмрд╛рд░ рдЧрд▓рдд compare-and-set рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдЬрд┐рддрдиреА рдЕрдзрд┐рдХ рдмрд╛рд░ рдЖрдкрдХреЛ рдЗрд╕ рдХреНрд░рд┐рдпрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

compare-and-set рдЖрдзрд╛рд░ рдкрд░, рдПрдХ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд░реАрдб рд▓реЙрдХ рднреА рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрд░рдорд╛рдгреБ рдЪрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдЧрд╛ред рдЧрдгрдирд╛ рд╕реЗ рдкрд╣рд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЧрдгрдирд╛ рдХреЗ рдмрд╛рдж рдЗрд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ read-write рддрд╛рд▓реЗ рддрднреА рдкреНрд░рднрд╛рд╡реА рд╣реЛрддреЗ рд╣реИрдВ рдЬрдм рд╕рдВрд╕реНрдХрд░рдг рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

 class Transaction { long debit } class Account { AtomicLong version = new AtomicLong() ReadWriteLock readWriteLock = new ReentrantReadWriteLock() List<Transaction> transactions = new ArrayList<Transaction>() } long balance(Account account) { ReentrantReadWriteLock.ReadLock locked while(true) { long balance = 0 long version = account.version.get() account.transactions.each {balance += it.debit} //volatile write for JMM if (account.version.compareAndSet(version, version)) { if (locked) {locked.unlock()} return balance } else { locked = account.readWriteLock.readLock() } } } void modifyTransaction(Account account, int position, long newDebit) { def writeLock = account.readWriteLock.writeLock() account.version.incrementAndGet() account.transactions[position].debit = newDebit writeLock.unlock() } 


рддрд╛рд▓реЗ

ReentrantLock

рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬреНрдб рддрд╛рд▓реЗ рдХреЗ рд╡рд┐рдкрд░реАрдд, ReentrantLock рдЕрдзрд┐рдХ рд▓рдЪреАрд▓реЗ рдврдВрдЧ рд╕реЗ рддрд╛рд▓реЛрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдХреНрд╖рдгреЛрдВ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдирд┐рдпрдорд┐рдд рдЬрд╛рд╡рд╛ рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, ReentrantLock рдЖрдкрдХреЛ рд▓реЙрдХ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдордп рдХреЗ рд▓рд┐рдП рд▓реЙрдХ рдХреЗ рд▓рд┐рдП "рдкреНрд░рддреАрдХреНрд╖рд╛" рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдПрдХ рд╣реА рдзрд╛рдЧреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрддрд┐ рдФрд░ рддрд╛рд▓реЗ рдХреА рд░рд┐рд╣рд╛рдИ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдИрдорд╛рдирджрд╛рд░ рддрд╛рд▓реЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдореЙрдирд┐рдЯрд░ рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд░рддреЗ рд╕рдордп рдЖрджреЗрд╢ рд░рдЦрдирд╛) - ReentrantLock рднреА рдЗрд╕ рддрдВрддреНрд░ рд╕реЗ рд▓реИрд╕ рд╣реИред

рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ syncronized рдФрд░ ReentrantLock рддрд╛рд▓реЗ рдмрд╣реБрдд рд╕рдорд╛рди рд╣реИрдВ - рдЬреЗрд╡реАрдПрдо рд╕реНрддрд░ рдкрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛рдлреА рдЕрд▓рдЧ рд╣реИред
рдЬреЗрдПрдордПрдо рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЬрд╛рдиреЗ рдХреЗ рдмрд┐рдирд╛: рдЬреЗрд╡реАрдПрдо рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬреНрдб рд▓реЙрдХ рдХреЗ рдмрдЬрд╛рдп ReentrantLock рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХреЗрд╡рд▓ рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реИ рдЕрдЧрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдореЙрдирд┐рдЯрд░ рдХреЗ рд▓рд┐рдП рдЕрдХреНрд╕рд░ рдереНрд░реЗрдбреНрд╕ рдХреА рд▓рдбрд╝рд╛рдИ рд╣реЛрддреА рд╣реИред рдорд╛рдорд▓реЗ рдореЗрдВ рдЬрдм рдХреЗрд╡рд▓ рдПрдХ рдзрд╛рдЧрд╛ рд╕рд┐рдВрдХрдЯреНрд░реЙрдирд┐рдХ рд╡рд┐рдзрд┐ рдореЗрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд░реЗрдиреНрдЯреНрд░реЗрдВрдЯрд▓реЙрдХ рдкреНрд░рджрд░реНрд╢рди рдЬреЗрд╡реАрдПрдо рд▓реЙрдХрд┐рдВрдЧ рддрдВрддреНрд░ ReentrantLock рдиреАрдЪ рд╣реИред

ReentrantReadWriteLock

рдХрдИ рдкрдврд╝рдиреЗ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рддрд╛рд▓реЗ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░рдиреЗ ReentrantLock рдХреНрд╖рдорддрд╛ рдХреЗ ReentrantLock рдЧреБрдгреЛрдВ рдХреА рдЖрдкреВрд░реНрддрд┐ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рд░реАрдб рд▓реЙрдХ рд╕реЗ рдкрд╣рд▓реЗ рд░рд╛рдЗрдЯ рд▓реЙрдХ рдХреЛ "рдХрдо" рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдореБрджреНрд░рд╛рдВрдХрд┐рддрд▓реЛрдХ _jdk 1.8_

рдпрд╣ рдЖрд╢рд╛рд╡рд╛рджреА рдФрд░ рдирд┐рд░рд╛рд╢рд╛рд╡рд╛рджреА рдкрдврд╝рдиреЗ-рд▓рд┐рдЦрдиреЗ рдХреЗ рддрд╛рд▓реЗ рдХреЛ рдЙрдирдХреЗ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдпрд╛ рдШрдЯрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЖрд╢рд╛рд╡рд╛рджреА рд▓реЙрдХрд┐рдВрдЧ рд▓реЙрдХ ( рдЬрд╛рд╡рджреЛрдХ ) рдХреЗ "рд╕реНрдЯреИрдореНрдк" рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 double distanceFromOriginV1() { // A read-only method long stamp; if ((stamp = sl.tryOptimisticRead()) != 0L) { // optimistic double currentX = x; double currentY = y; if (sl.validate(stamp)) return Math.sqrt(currentX * currentX + currentY * currentY); } stamp = sl.readLock(); // fall back to read lock try { double currentX = x; double currentY = y; return Math.sqrt(currentX * currentX + currentY * currentY); } finally { sl.unlockRead(stamp); } } 


рд╕рдВрдЧреНрд░рд╣

ArrayBlockingQueue

рдПрдХ рдереНрд░реЗрдб рд╕реЗ рджреВрд╕рд░реЗ рдореЗрд╕реЗрдЬ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдИрдорд╛рдирджрд╛рд░ рдХрддрд╛рд░ред рдЕрд╡рд░реЛрдзрдХ ( put() take() ) рдФрд░ рдиреЙрдирдмреНрд▓реЙрдХрд┐рдВрдЧ ( offer() pool() offer() рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рдирд┐рд╖рд┐рджреНрдз рдореВрд▓реНрдпреЛрдВ рдХреЛ рдирд┐рд╖рд┐рджреНрдз рдХрд░рддрд╛ рд╣реИред рдирд┐рд░реНрдорд╛рдг рдкрд░ рдХрддрд╛рд░ рдХреА рдХреНрд╖рдорддрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред

ConcurrentHashMap

hash рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдХреБрдВрдЬреА-рдореВрд▓реНрдп рд╕рдВрд░рдЪрдирд╛ред рдкрдврд╝рдиреЗ рдХреЗ рддрд╛рд▓реЗ рдирд╣реАрдВ рд╣реИрдВред рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдХрд░рддреЗ рд╕рдордп, рдХрд╛рд░реНрдб рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рд╣рд┐рд╕реНрд╕рд╛ (рдЦрдВрдб) рдЕрд╡рд░реБрджреНрдз рд╣реЛрддрд╛ рд╣реИред рд╕реЗрдЧрдореЗрдВрдЯ рдХреА рд╕рдВрдЦреНрдпрд╛ рдирд┐рдХрдЯрддрдо рдбрд┐рдЧреНрд░реА 2 рддрдХ рд╕реАрдорд┐рдд рд╣реИред

ConcurrentSkipListMap

рдмреИрд▓реЗрдВрд╕реНрдб рдорд▓реНрдЯреАрдереНрд░реЗрдбреЗрдб рдХреА-рд╡реИрд▓реНрдпреВ рд╕реНрдЯреНрд░рдХреНрдЪрд░ (O (рд▓реЙрдЧ рдПрди))ред рдЦреЛрдЬ рдПрдХ рд╕реНрдХрд┐рдк рдХреА рдЧрдИ рд╕реВрдЪреА рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рдХрд╛рд░реНрдб рдХреЛ рдЪрд╛рдмрд┐рдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

ConcurrentSkipListSet

рдореВрд▓реНрдпреЛрдВ рдХреЗ рдмрд┐рдирд╛ ConcurrentSkipListMap ред

CopyOnWriteArrayList

рдПрдХ рд░рд╛рдЗрдЯ-рдмреНрд▓реЙрдХ, рдЧреИрд░-рд░реАрдб-рдмреНрд▓реЙрдХ рд╕реВрдЪреАред рдХреЛрдИ рднреА рд╕рдВрд╢реЛрдзрди рд╕реНрдореГрддрд┐ рдореЗрдВ рд╕рд░рдгреА рдХрд╛ рдПрдХ рдирдпрд╛ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддрд╛ рд╣реИред

CopyOnWriteArraySet

CopyOnWriteArrayList рдмрд┐рдирд╛ CopyOnWriteArrayList ред

DelayQueue

PriorityBlockingQueue рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рджреЗрд░реА рдХреЗ рдмрд╛рдж рд╣реА рдПрдХ рддрддреНрд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рджреЗрд░реА рдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ Delayed рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рдПрдХ рдЕрдиреБрд╕реВрдЪрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП DelayQueue рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХрддрд╛рд░ рдХреА рдХреНрд╖рдорддрд╛ рддрдп рдирд╣реАрдВ рд╣реИред

LinkedBlockingDeque

рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рджреНрд╡рд┐рджрд┐рд╢ BlockingQueue рдХреНрдпреВ (рдХреИрд╢-рдорд┐рд╕ рдПрдВрдб рдХреИрд╢ рдХреЛрд╣реЗрд░реЗрдВрд╕ рдУрд╡рд░рд╣реЗрдб)ред рдХрддрд╛рд░ рдХреА рдХреНрд╖рдорддрд╛ рддрдп рдирд╣реАрдВ рд╣реИред

LinkedBlockingQueue

рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдпреВрдирд┐рдбрд╛рдпрд░реЗрдХреНрд╢рдирд▓ BlockingQueue рдХреНрдпреВ (рдХреИрд╢реЗ-рдорд┐рд╕ рдПрдВрдб рдХреИрд╢ рдХреЛрд╣реЗрд░реЗрдВрд╕ рдУрд╡рд░рд╣реЗрдб)ред рдХрддрд╛рд░ рдХреА рдХреНрд╖рдорддрд╛ рддрдп рдирд╣реАрдВ рд╣реИред

LinkedTransferQueue

рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдпреВрдирд┐рдбрд╛рдпрд░реЗрдХреНрд╢рдирд▓ `рдмреНрд▓реЙрдХрд┐рдВрдЧрдХреНрдпреВрдПрдпреВ` (рдХреИрд╢-рдорд┐рд╕ рдПрдВрдб рдХреИрд╢ рдХреЛрд╣реЗрд░реЗрдВрд╕ рдУрд╡рд░рд╣реЗрдб)ред рдХрддрд╛рд░ рдХреА рдХреНрд╖рдорддрд╛ рддрдп рдирд╣реАрдВ рд╣реИред рдпрд╣ рдХрддрд╛рд░ рдЖрдкрдХреЛ рд╣реИрдВрдбрд▓рд░ рдХреЛ рддрддреНрд╡ рдЪреБрдирдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред

PriorityBlockingQueue

рдпреВрдирд┐рдбрд╛рдпрд░реЗрдХреНрд╢рдирд▓ `рдмреНрд▓реЙрдХрд┐рдВрдЧрдХреНрдпреВрдПрдпреВ`, рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреЗрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рддрддреНрд╡реЛрдВ рдХреА рддреБрд▓рдирд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ)ред рдирд┐рд╖рд┐рджреНрдз рдореВрд▓реНрдпреЛрдВ рдХреЛ рдирд┐рд╖рд┐рджреНрдз рдХрд░рддрд╛ рд╣реИред

SynchronousQueue

рдПрдХ рдпреВрдирд┐рдбрд╛рдпрд░реЗрдХреНрд╢рдирд▓ `BlockingQueue` рдЬреЛ put() рд▓рд┐рдП transfer() рддрд░реНрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред

рддреБрд▓реНрдпрдХрд╛рд▓рди рдЕрдВрдХ

CountDownLatch

рдПрдХ рдЕрд╡рд░реЛрдз ( await() ) рдЬреЛ countDown() рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ (рдпрд╛ рдЕрдзрд┐рдХ) рдХреЙрд▓реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред рдмрд╛рдзрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд░реАрд╕реЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

CyclicBarrier

рдПрдХ рдмрд╛рдзрд╛ ( await() ) рдЬреЛ рдЕрдиреНрдп рдереНрд░реЗрдбреНрд╕ рджреНрд╡рд╛рд░рд╛ await() рдХреЙрд▓ рдХреА рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдХреА await() рдХрд░рддреА рд╣реИред рдЬрдм рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рддрдХ рдкрд╣реБрдВрдЪ рдЬрд╛рддреА рд╣реИ, рддреЛ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдХреЙрд▓рдмреИрдХ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд▓реЙрдХ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЕрд╡рд░реЛрдз рдЕрдкрдиреЗ рд░рд╛рдЬреНрдп рдХреЛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рд╕реНрдерд╛ рдореЗрдВ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рд▓рдВрдмрд┐рдд рдкреНрд░рд╡рд╛рд╣ рдЬрд╛рд░реА рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдПрдХреНрд╕рдЪреЗрдВрдЬрд░

рджреЛ рдереНрд░реЗрдбреНрд╕ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреИрд░рд┐рдпрд░ (`рдПрдХреНрд╕рдЪреЗрдВрдЬ ()`)ред рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд╕рдордп, рдереНрд░реЗрдбреНрд╕ рдХреЗ рдмреАрдЪ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЕрд╕реНрдерд┐рд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рд╕рдВрднрд╡ рд╣реИред

Phaser

рд╡рд┐рд╕реНрддрд╛рд░ `CyclicBarrier`, рдмрд╛рдзрд╛ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдЪрдХреНрд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рднрд╛рдЧрд┐рдпреЛрдВ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдФрд░ рд╣рдЯрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рд╕рд┐рдХрдВрджрд░рд╛

рдореЙрдирд┐рдЯрд░ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдереНрд░реЗрдб рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рд╡рд╛рд▓рд╛ рдЕрд╡рд░реЛрдзред рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ `рд▓реЙрдХ` рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдХрдИ рдереНрд░реЗрдб рдореЗрдВ рдмреНрд▓реЙрдХ рдореЗрдВ рд╣реЛрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИред

рдирд┐рд╖реНрдкрд╛рджрдХреЛрдВ


ExecutorService рдиреЗ new Thread(runnable) рд╕рд╛рде рдХрд╛рдо рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП new Thread(runnable) рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ред ExecutorService рдореБрдХреНрдд рдереНрд░реЗрдб рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ, рдереНрд░реЗрдб рдкреВрд▓ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рдХрддрд╛рд░реЗрдВ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдХрд╛рд░реНрдп рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрддрд╛ рд╣реИред Runnable рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдмрдЬрд╛рдп, рдкреВрд▓ Runnable рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ (рдпрд╣ рдПрдХ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдлреЗрдВрдХ рд╕рдХрддрд╛ рд╣реИ)ред

 ExecutorService pool = Executors.newFixedThreadPool(4) Future future = pool.submit(new Callable() { Object call() throws Exception { println("In thread") return "From thread" } }) println("From main") println(future.get()) try { pool.submit(new Callable() { Object call() throws Exception { throw new IllegalStateException() } }).get() } catch (ExecutionException e) {println("Got it: ${e.cause}")} pool.shutdown() 


invokeAll рд╡рд┐рдзрд┐ рдХреЙрд▓рд┐рдВрдЧ рдереНрд░реЗрдб рдХреЛ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░ рд╣реА рдирд┐рдпрдВрддреНрд░рдг рджреЗрддреА рд╣реИред invokeAny рд╡рд┐рдзрд┐ рдкрд╣рд▓реЗ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреВрд░реНрдг рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдп рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрддреА рд╣реИ, рдмрд╛рдж рдХреЗ рд╕рднреА рдХреЛ рд░рджреНрдж рдХрд░ рджреЗрддреА рд╣реИред

ThreadPoolExecutor

рдкреВрд▓ рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдФрд░ рдереНрд░реЗрдбреНрд╕ рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдереНрд░реЗрдбреНрд╕ рдХрд╛ рдПрдХ рдкреВрд▓, рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрддрд╛рд░ред

ScheduledThreadPoolExecutor

рдХрд╛рд░реНрдп рдХреЛ рд╕реНрдердЧрд┐рдд рдпрд╛ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдХрд░рдиреЗ ThreadPoolExecutor рдХреНрд╖рдорддрд╛ рдХреЗ ThreadPoolExecutor рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИред

ThreadPoolExecutor

рдЖрддреНрдо-рдкреНрд░рддрд┐рдХреГрддрд┐ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рд▓реНрдХрд╛ рдзрд╛рдЧрд╛ рдкреВрд▓ред рдкреВрд▓ рдХреЛ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдореЗрдВ рдмрдЪреНрдЪреЗ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ `рдлреЛрд░реНрдХ ()` рдФрд░ `рдЬреНрд╡рд╛рдЗрди () рддрд░реАрдХреЗ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред

 class LNode { List<LNode> childs = [] def object } class Finder extends RecursiveTask<LNode> { LNode node Object expect protected LNode compute() { if (node?.object?.equals(expect)) { return node } node?.childs?.collect { new Finder(node: it, expect: expect).fork() }?.collect { it.join() }?.find { it != null } } } ForkJoinPool es = new ForkJoinPool() def invoke = es.invoke(new Finder( node: new LNode( childs: [ new LNode(object: "ivalid"), new LNode( object: "ivalid", childs: [new LNode(object: "test")] ) ] ), expect: "test" )) print("${invoke?.object}") 


рд╕рдВрдЪрд╛рдпрдХ _jdk 1.8_

рдмреИрдЯрд░рд┐рдпреЛрдВ рдЖрдк рдХреИрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рдПрдХ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рддрддреНрд╡реЛрдВ рдкрд░ рдЖрджрд┐рдо рд╕рдВрдЪрд╛рд▓рди (рдпреЛрдЧ / рдЕрдзрд┐рдХрддрдо рдореВрд▓реНрдп рдЦреЛрдЬ) рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/In187854/


All Articles