volatile 关键字-内存可见性
package com. atguigu. juc;
public class TestVolatile {
public static void main ( String[ ] args) {
ThreadDemo td = new ThreadDemo ( ) ;
new Thread ( td) . start ( ) ;
while ( true ) {
if ( td. isFlag ( ) ) {
System. out. println ( "--------------------" ) ;
break ;
}
}
}
}
class ThreadDemo implements Runnable {
private volatile boolean flag = false ;
@Override
public void run ( ) {
try {
Thread. sleep ( 200 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
flag = true ;
System. out. println ( "flag=" + isFlag ( ) ) ;
}
public boolean isFlag ( ) {
return flag;
}
public void setFlag ( boolean flag) {
this . flag = flag;
}
}
原子变量-CAS算法
package com. atguigu. juc;
import java. util. concurrent. atomic. AtomicInteger;
public class TestAtomicDemo {
public static void main ( String[ ] args) {
AtomicDemo ad = new AtomicDemo ( ) ;
for ( int i = 0 ; i < 10 ; i++ ) {
new Thread ( ad) . start ( ) ;
}
}
}
class AtomicDemo implements Runnable {
private AtomicInteger serialNumber = new AtomicInteger ( ) ;
public int getSerialNumber ( ) {
return serialNumber. getAndIncrement ( ) ;
}
@Override
public void run ( ) {
try {
Thread. sleep ( 200 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
System. out. println ( Thread. currentThread ( ) . getName ( ) + ":" + getSerialNumber ( ) ) ;
}
}
package com. atguigu. juc;
public class TestCompareAndSwap {
public static void main ( String[ ] args) {
final CompareAndSwap cas = new CompareAndSwap ( ) ;
for ( int i = 0 ; i < 10 ; i++ ) {
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
int expectedValue = cas. get ( ) ;
boolean b = cas. compareAndSet ( expectedValue, ( int ) ( Math. random ( ) * 101 ) ) ;
System. out. println ( b) ;
}
} ) . start ( ) ;
}
}
}
class CompareAndSwap {
private int value;
public synchronized int get ( ) {
return value;
}
public synchronized int compareAndSwap ( int expecteValue, int newValue) {
int oldValue = value;
if ( oldValue == expecteValue) {
this . value = newValue;
}
return oldValue;
}
public synchronized boolean compareAndSet ( int expectedVale, int newValue) {
return expectedVale == compareAndSwap ( expectedVale, newValue) ;
}
}
ConcurrentHashMap锁分段机制
package com. atguigu. juc;
import java. util. Iterator;
import java. util. List;
import java. util. concurrent. CopyOnWriteArrayList;
public class TestCopyOnWriteArrayList {
public static void main ( String[ ] args) {
HelloThread ht = new HelloThread ( ) ;
for ( int i = 0 ; i < 10 ; i++ ) {
new Thread ( ht) . start ( ) ;
}
}
}
class HelloThread implements Runnable {
private static List< String> list = new CopyOnWriteArrayList < > ( ) ;
static {
list. add ( "AA" ) ;
list. add ( "BB" ) ;
list. add ( "CC" ) ;
}
@Override
public void run ( ) {
Iterator< String> it = list. iterator ( ) ;
while ( it. hasNext ( ) ) {
System. out. println ( it. next ( ) ) ;
list. add ( "AA" ) ;
}
}
}
CountDownLatch闭锁
package com. atguigu. juc;
import java. util. concurrent. CountDownLatch;
public class TestCountDownLatch {
public static void main ( String[ ] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch ( 5 ) ;
LatchDemo ld = new LatchDemo ( latch) ;
long start = System. currentTimeMillis ( ) ;
for ( int i = 0 ; i < 5 ; i++ ) {
new Thread ( ld) . start ( ) ;
}
latch. await ( ) ;
long end = System. currentTimeMillis ( ) ;
System. out. println ( "-----------" + ( end - start) ) ;
}
}
class LatchDemo implements Runnable {
private CountDownLatch latch;
public LatchDemo ( CountDownLatch latch) {
this . latch = latch;
}
@Override
public void run ( ) {
synchronized ( this ) {
try {
for ( int i = 0 ; i < 50000 ; i++ ) {
if ( i % 2 == 0 ) {
System. out. println ( i) ;
}
}
} finally {
latch. countDown ( ) ;
}
}
}
}
实现Callable接口
package com. atguigu. juc;
import java. util. concurrent. Callable;
import java. util. concurrent. ExecutionException;
import java. util. concurrent. FutureTask;
public class TestCallable {
public static void main ( String[ ] args) throws ExecutionException, InterruptedException {
ThreadDemo1 td = new ThreadDemo1 ( ) ;
FutureTask< Integer> result = new FutureTask < > ( td) ;
new Thread ( result) . start ( ) ;
System. out. println ( result. get ( ) ) ;
System. out. println ( "---------------------------------" ) ;
}
}
class ThreadDemo1 implements Callable < Integer> {
@Override
public Integer call ( ) throws Exception {
int sum = 0 ;
for ( int i = 0 ; i <= 100 ; i++ ) {
sum += i;
}
return sum;
}
}
Lock同步锁
package com. atguigu. juc;
import java. util. concurrent. locks. Lock;
import java. util. concurrent. locks. ReentrantLock;
public class TestLock {
public static void main ( String[ ] args) {
Ticket ticket = new Ticket ( ) ;
new Thread ( ticket, "1号" ) . start ( ) ;
new Thread ( ticket, "2号" ) . start ( ) ;
new Thread ( ticket, "3号" ) . start ( ) ;
}
}
class Ticket implements Runnable {
private int tick = 100 ;
private Lock lock = new ReentrantLock ( ) ;
@Override
public void run ( ) {
while ( true ) {
lock. lock ( ) ;
try {
if ( tick > 0 ) {
try {
Thread. sleep ( 200 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
System. out. println ( Thread. currentThread ( ) + "完成售票,余票为:" + -- tick) ;
}
} finally {
lock. unlock ( ) ;
}
}
}
}
生产者消费者案例-虚假唤醒
Condition控制线程通信
package com. atguigu. juc;
import java. util. concurrent. locks. Condition;
import java. util. concurrent. locks. Lock;
import java. util. concurrent. locks. ReentrantLock;
public class TestProductAndConsumer {
public static void main ( String[ ] args) {
Clerk clerk = new Clerk ( ) ;
Productor productor = new Productor ( clerk) ;
Consumer consumer = new Consumer ( clerk) ;
new Thread ( productor, "生产者A" ) . start ( ) ;
new Thread ( consumer, "消费者B" ) . start ( ) ;
new Thread ( productor, "生产者C" ) . start ( ) ;
new Thread ( consumer, "消费者D" ) . start ( ) ;
}
}
class Clerk {
private int product = 0 ;
private Lock lock = new ReentrantLock ( ) ;
private Condition condition = lock. newCondition ( ) ;
public void get ( ) {
lock. lock ( ) ;
try {
while ( product >= 1 ) {
System. out. println ( "产品已满" ) ;
try {
condition. await ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
System. out. println ( Thread. currentThread ( ) . getName ( ) + ":" + ++ product) ;
condition. signalAll ( ) ;
} finally {
lock. unlock ( ) ;
}
}
public void sale ( ) {
lock. lock ( ) ;
try {
while ( product <= 0 ) {
System. out. println ( "缺货" ) ;
try {
condition. await ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
System. out. println ( Thread. currentThread ( ) . getName ( ) + ":" + -- product) ;
condition. signalAll ( ) ;
} finally {
lock. unlock ( ) ;
}
}
}
class Productor implements Runnable {
private Clerk clerk;
public Productor ( Clerk clerk) {
this . clerk = clerk;
}
@Override
public void run ( ) {
for ( int i = 0 ; i < 20 ; i++ ) {
try {
Thread. sleep ( 200 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
clerk. get ( ) ;
}
}
}
class Consumer implements Runnable {
private Clerk clerk;
public Consumer ( Clerk clerk) {
this . clerk = clerk;
}
@Override
public void run ( ) {
for ( int i = 0 ; i < 20 ; i++ ) {
clerk. sale ( ) ;
}
}
}
线程八锁
package com. atguigu. juc;
public class TestThread8Monitor {
public static void main ( String[ ] args) {
Number number = new Number ( ) ;
Number number2 = new Number ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
number. getOne ( ) ;
}
} ) . start ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
number2. getTwo ( ) ;
}
} ) . start ( ) ;
}
}
class Number {
public static synchronized void getOne ( ) {
try {
Thread. sleep ( 3000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
System. out. println ( "one" ) ;
}
public static synchronized void getTwo ( ) {
System. out. println ( "two" ) ;
}
}
线程按序交替
package com. atguigu. juc;
import java. util. concurrent. locks. Condition;
import java. util. concurrent. locks. Lock;
import java. util. concurrent. locks. ReentrantLock;
public class TestABCAlternate {
public static void main ( String[ ] args) {
AternateDemo ad = new AternateDemo ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( int i = 0 ; i <= 20 ; i++ ) {
ad. loopA ( i) ;
}
}
} , "A" ) . start ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( int i = 0 ; i <= 20 ; i++ ) {
ad. loopB ( i) ;
}
}
} , "B" ) . start ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( int i = 0 ; i <= 20 ; i++ ) {
ad. loopC ( i) ;
System. out. println ( "-----------------------" ) ;
}
}
} , "C" ) . start ( ) ;
}
}
class AternateDemo {
private int number = 1 ;
private Lock lock = new ReentrantLock ( ) ;
private Condition condition1 = lock. newCondition ( ) ;
private Condition condition2 = lock. newCondition ( ) ;
private Condition condition3 = lock. newCondition ( ) ;
public void loopA ( int totalLoop) {
lock. lock ( ) ;
try {
if ( number != 1 ) {
condition1. await ( ) ;
}
for ( int i = 0 ; i < 5 ; i++ ) {
System. out. println ( Thread. currentThread ( ) . getName ( ) + "\t" + i + "\t" + totalLoop) ;
}
number = 2 ;
condition2. signal ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
} finally {
lock. unlock ( ) ;
}
}
public void loopB ( int totalLoop) {
lock. lock ( ) ;
try {
if ( number != 2 ) {
condition2. await ( ) ;
}
for ( int i = 0 ; i < 15 ; i++ ) {
System. out. println ( Thread. currentThread ( ) . getName ( ) + "\t" + i + "\t" + totalLoop) ;
}
number = 3 ;
condition3. signal ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
} finally {
lock. unlock ( ) ;
}
}
public void loopC ( int totalLoop) {
lock. lock ( ) ;
try {
if ( number != 3 ) {
condition3. await ( ) ;
}
for ( int i = 0 ; i < 20 ; i++ ) {
System. out. println ( Thread. currentThread ( ) . getName ( ) + "\t" + i + "\t" + totalLoop) ;
}
number = 1 ;
condition1. signal ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
} finally {
lock. unlock ( ) ;
}
}
}
ReadWriteLock读写锁
package com. atguigu. juc;
import java. util. concurrent. locks. ReadWriteLock;
import java. util. concurrent. locks. ReentrantReadWriteLock;
public class TestReadWriteLock {
public static void main ( String[ ] args) {
ReadWriteLockDemo rw = new ReadWriteLockDemo ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
rw. set ( ( int ) ( Math. random ( ) * 101 ) ) ;
}
} , "write" ) . start ( ) ;
for ( int i = 0 ; i < 100 ; i++ ) {
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
rw. get ( ) ;
}
} , "read" ) . start ( ) ;
}
}
}
class ReadWriteLockDemo {
private int number = 0 ;
private ReadWriteLock lock = new ReentrantReadWriteLock ( ) ;
public void get ( ) {
lock. readLock ( ) . lock ( ) ;
try {
System. out. println ( Thread. currentThread ( ) . getName ( ) + ":" + number) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
} finally {
lock. readLock ( ) . unlock ( ) ;
}
}
public void set ( int number) {
lock. writeLock ( ) . lock ( ) ;
try {
System. out. println ( Thread. currentThread ( ) . getName ( ) ) ;
this . number = number;
} catch ( Exception e) {
e. printStackTrace ( ) ;
} finally {
lock. writeLock ( ) . unlock ( ) ;
}
}
}
线程池
package com. atguigu. juc;
import java. util. ArrayList;
import java. util. List;
import java. util. concurrent. *;
public class TestThreadPool {
public static void main ( String[ ] args) throws ExecutionException, InterruptedException {
ExecutorService pool = Executors. newFixedThreadPool ( 5 ) ;
List< Future< Integer> > list = new ArrayList < > ( ) ;
for ( int i = 0 ; i < 10 ; i++ ) {
Future< Integer> future = pool. submit ( new Callable < Integer> ( ) {
@Override
public Integer call ( ) throws Exception {
int sum = 0 ;
for ( int i = 0 ; i <= 100 ; i++ ) {
sum += i;
}
return sum;
}
} ) ;
list. add ( future) ;
}
pool. shutdown ( ) ;
for ( Future< Integer> future : list) {
System. out. println ( future. get ( ) ) ;
}
}
}
class ThreadPoolDemo implements Runnable {
private int i = 0 ;
@Override
public void run ( ) {
while ( i <= 100 ) {
System. out. println ( Thread. currentThread ( ) . getName ( ) + ":" + i++ ) ;
}
}
}
线程调度
package com. atguigu. juc;
import java. util. Random;
import java. util. concurrent. *;
public class TestScheduledThreadPool {
public static void main ( String[ ] args) throws ExecutionException, InterruptedException {
ScheduledExecutorService pool = Executors. newScheduledThreadPool ( 5 ) ;
for ( int i = 0 ; i < 10 ; i++ ) {
Future< Integer> result = pool. schedule ( new Callable < Integer> ( ) {
@Override
public Integer call ( ) throws Exception {
int num = new Random ( ) . nextInt ( 100 ) ;
System. out. println ( Thread. currentThread ( ) . getName ( ) + ":" + num) ;
return num;
}
} , 3 , TimeUnit. SECONDS) ;
System. out. println ( result. get ( ) ) ;
}
pool. shutdown ( ) ;
}
}
ForkJoinPool分支/合并框架 工作窃取
Fork/Join框架:就是在必要的情况下,将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行join汇总 Fork/Join 框架与线程池的区别 采用“工作窃取”模式(work-stealing): 当执行新的任务时它可以将其拆分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。 如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态。 而在fork/join框架实现中,如果某个子问题由于等待另外一个子问题的完成而无法继续运行。那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行,这种方式减少了线程的等待时间,提高了性能。
package com. atguigu. juc;
import org. junit. Test;
import java. util. concurrent. ForkJoinPool;
import java. util. concurrent. ForkJoinTask;
import java. util. concurrent. RecursiveTask;
import java. util. stream. LongStream;
public class TestForkJoinPool {
public static void main ( String[ ] args) {
ForkJoinPool pool = new ForkJoinPool ( ) ;
ForkJoinTask< Long> task = new ForkJoinSunCalculate ( 0 L, 1000000000 L) ;
Long sum = pool. invoke ( task) ;
System. out. println ( sum) ;
pool. shutdown ( ) ;
}
@Test
public void test1 ( ) {
Long sum = LongStream. rangeClosed ( 0 L, 1000000 L)
. parallel ( )
. reduce ( 0 L, Long: : sum) ;
System. out. println ( sum) ;
}
}
class ForkJoinSunCalculate extends RecursiveTask < Long> {
private long start;
private long end;
private static final long THURSHOLD = 10000 L;
public ForkJoinSunCalculate ( long state, long end) {
this . start = state;
this . end = end;
}
@Override
protected Long compute ( ) {
long length = end - start;
if ( length <= THURSHOLD) {
long sum = 0 L;
for ( long i = start; i <= end; i++ ) {
sum += i;
}
return sum;
} else {
long middle = ( start + end) / 2 ;
ForkJoinSunCalculate left = new ForkJoinSunCalculate ( start, middle) ;
left. fork ( ) ;
ForkJoinSunCalculate right = new ForkJoinSunCalculate ( middle + 1 , end) ;
right. fork ( ) ;
return left. join ( ) + right. join ( ) ;
}
}
}