рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЬрд╛рд╡рд╛ рдореЗрдВ рдореМрдЬреВрдж рдореЗрдореЛрд░реА рдореЙрдбрд▓ рдЗрд╕ рдХреЛрдб рдореЗрдВ рдереНрд░реЗрдб рд░реЗрд╕рд┐рдВрдЧ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рдХреЛрдб рдХреЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдирд┐рд╖реНрдкрд╛рджрди рдЖрджреЗрд╢ рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИред рдФрд░ рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рд░реЗрд╕рд┐рдВрдЧ рд╕реЗ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдирдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдФрд░ рдПрдХреНрд╕рдЪреЗрдВрдЬ рдХрд░рдиреЗ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
HotSpot JDK рдХреЗ рд╕рд╛рде рд╢рд╛рдорд┐рд▓
java.util.concurrent
рдкреИрдХреЗрдЬ рдореЗрдВ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЯреВрд▓ рджрд┐рдП рдЧрдП рд╣реИрдВ:
- рдкрд░рдорд╛рдгреБ
- рддрд╛рд▓реЗ
- рд╕рдВрдЧреНрд░рд╣
- рддреБрд▓реНрдпрдХрд╛рд▓рди рдЕрдВрдХ
- рдирд┐рд╖реНрдкрд╛рджрдХреЛрдВ
- рд╕рдВрдЪрд╛рдпрдХ _jdk 1.8_
рдкрд░рдорд╛рдгреБ
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}
рддрд╛рд▓реЗ
ReentrantLock
рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬреНрдб рддрд╛рд▓реЗ рдХреЗ рд╡рд┐рдкрд░реАрдд,
ReentrantLock
рдЕрдзрд┐рдХ рд▓рдЪреАрд▓реЗ рдврдВрдЧ рд╕реЗ рддрд╛рд▓реЛрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдХреНрд╖рдгреЛрдВ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдирд┐рдпрдорд┐рдд рдЬрд╛рд╡рд╛ рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛,
ReentrantLock
рдЖрдкрдХреЛ рд▓реЙрдХ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдордп рдХреЗ рд▓рд┐рдП рд▓реЙрдХ рдХреЗ рд▓рд┐рдП "рдкреНрд░рддреАрдХреНрд╖рд╛" рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдПрдХ рд╣реА рдзрд╛рдЧреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрддрд┐ рдФрд░ рддрд╛рд▓реЗ рдХреА рд░рд┐рд╣рд╛рдИ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдИрдорд╛рдирджрд╛рд░ рддрд╛рд▓реЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдореЙрдирд┐рдЯрд░ рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд░рддреЗ рд╕рдордп рдЖрджреЗрд╢ рд░рдЦрдирд╛) -
ReentrantLock
рднреА рдЗрд╕ рддрдВрддреНрд░ рд╕реЗ рд▓реИрд╕ рд╣реИред
рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐
syncronized
рдФрд░
ReentrantLock
рддрд╛рд▓реЗ рдмрд╣реБрдд рд╕рдорд╛рди рд╣реИрдВ - рдЬреЗрд╡реАрдПрдо рд╕реНрддрд░ рдкрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛рдлреА рдЕрд▓рдЧ рд╣реИред
рдЬреЗрдПрдордПрдо рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЬрд╛рдиреЗ рдХреЗ рдмрд┐рдирд╛: рдЬреЗрд╡реАрдПрдо рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬреНрдб рд▓реЙрдХ рдХреЗ рдмрдЬрд╛рдп
ReentrantLock
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХреЗрд╡рд▓ рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реИ рдЕрдЧрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдореЙрдирд┐рдЯрд░ рдХреЗ рд▓рд┐рдП рдЕрдХреНрд╕рд░ рдереНрд░реЗрдбреНрд╕ рдХреА рд▓рдбрд╝рд╛рдИ рд╣реЛрддреА рд╣реИред рдорд╛рдорд▓реЗ рдореЗрдВ рдЬрдм рдХреЗрд╡рд▓ рдПрдХ рдзрд╛рдЧрд╛ рд╕рд┐рдВрдХрдЯреНрд░реЙрдирд┐рдХ рд╡рд┐рдзрд┐ рдореЗрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд░реЗрдиреНрдЯреНрд░реЗрдВрдЯрд▓реЙрдХ рдкреНрд░рджрд░реНрд╢рди рдЬреЗрд╡реАрдПрдо рд▓реЙрдХрд┐рдВрдЧ рддрдВрддреНрд░
ReentrantLock
рдиреАрдЪ рд╣реИред
ReentrantReadWriteLock
рдХрдИ рдкрдврд╝рдиреЗ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рддрд╛рд▓реЗ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░рдиреЗ
ReentrantLock
рдХреНрд╖рдорддрд╛ рдХреЗ
ReentrantLock
рдЧреБрдгреЛрдВ рдХреА рдЖрдкреВрд░реНрддрд┐ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рд░реАрдб рд▓реЙрдХ рд╕реЗ рдкрд╣рд▓реЗ рд░рд╛рдЗрдЯ рд▓реЙрдХ рдХреЛ "рдХрдо" рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдореБрджреНрд░рд╛рдВрдХрд┐рддрд▓реЛрдХ _jdk 1.8_
рдпрд╣ рдЖрд╢рд╛рд╡рд╛рджреА рдФрд░ рдирд┐рд░рд╛рд╢рд╛рд╡рд╛рджреА рдкрдврд╝рдиреЗ-рд▓рд┐рдЦрдиреЗ рдХреЗ рддрд╛рд▓реЗ рдХреЛ рдЙрдирдХреЗ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдпрд╛ рдШрдЯрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЖрд╢рд╛рд╡рд╛рджреА рд▓реЙрдХрд┐рдВрдЧ рд▓реЙрдХ (
рдЬрд╛рд╡рджреЛрдХ ) рдХреЗ "рд╕реНрдЯреИрдореНрдк" рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
double distanceFromOriginV1() {
рд╕рдВрдЧреНрд░рд╣
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_
рдмреИрдЯрд░рд┐рдпреЛрдВ рдЖрдк рдХреИрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рдПрдХ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рддрддреНрд╡реЛрдВ рдкрд░ рдЖрджрд┐рдо рд╕рдВрдЪрд╛рд▓рди (рдпреЛрдЧ / рдЕрдзрд┐рдХрддрдо рдореВрд▓реНрдп рдЦреЛрдЬ) рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред