java juc2

来源:互联网 发布:阿里云搭建个人网站 编辑:程序博客网 时间:2024/06/07 13:39

一,线程交替测试

试题:编写一段程序,开启三个线程,线程ID分别为A,B,C;按一定顺序打印线程ID,如ABCABC

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** *轮询打印ABC,按顺序执行,例如ABCABCABC * :使用Lock Condition */public class ABCTest {    static int number=0;    public ABCTest() {    }    static Lock lock = new ReentrantLock();    static Condition condition1 = lock.newCondition();    static Condition condition2 = lock.newCondition();    static Condition condition3 = lock.newCondition();    public static void main(String[] args) {        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i < 10; i++) {                    loopA();                }            }        },"A").start();        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i <10; i++) {                    loopB();                }            }        },"B").start();        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i < 10; i++) {                    loopC();                }            }        },"C").start();    }    public static void loopA() {        lock.lock();        try {            if (number != 0) {                try {                    condition1.await();                } catch (InterruptedException e) {                }            }            //for (int i = 0; i < 5; i++) {                System.out.println("A");           // }            number++;            condition2.signal();        }finally {            lock.unlock();        }    }    public static void loopB() {        lock.lock();        try {            if (number != 1) {                try {                    condition2.await();                } catch (InterruptedException e) {                }            }            for (int i = 0; i < 1; i++) {                System.out.println("B");            }            number++;            condition3.signal();        }finally {            lock.unlock();        }    }    public static void loopC() {        lock.lock();        try {            if (number != 2) {                try {                    condition3.await();                } catch (InterruptedException e) {                }            }            for (int i = 0; i < 1; i++) {                System.out.println("C");            }            System.out.println(".............................");            number=number-2;            condition1.signal();        }finally {            lock.unlock();        }    }}
二,读写锁ReadWriteLock

1,多个线程同时读不涉及安全问题

2,多个线程里面有多读一写或多写涉及安全问题

也就是说:读读"不互斥"

读写/写写"互斥"

public class ReadWriteLockTestMain {    public static void main(String[] args) {        final ReadWriteLockTest readWriteLockTest = new ReadWriteLockTest();        for (int i = 0; i < 100; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    readWriteLockTest.setNumber((int) (Math.random()*101));                }            },"write:").start();        }        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i < 10; i++) {                    readWriteLockTest.getNumber();                }            }        },"read:").start();    }}
import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;/** * Created by 13795 on 2017/9/19. */public class ReadWriteLockTest {     int number=0;     ReadWriteLock readWriteLock = new ReentrantReadWriteLock();    public  void getNumber(){        readWriteLock.readLock().lock();        try {            System.out.println(Thread.currentThread().getName()+" : "+number);        }finally {            readWriteLock.readLock().unlock();        }    };    public  void setNumber(int number) {        readWriteLock.writeLock().lock();        try {            System.out.println(Thread.currentThread().getName()+" : "+number);            this.number = number;        }finally {            readWriteLock.writeLock().unlock();        }    }}


三,线程八锁

1,两个普通同步方法,两个线程,标准打印,结果:one two

2,新增Thread.sleep()给getone(),结果:one two

3,新增普通方法getThree(),结果three one two

4,两个同步方法,两个number对象;结果:two three one

5,修改getOne()方法为静态方法;结果:two three  one

6,修改两个方法均为静态方法,一个number对象;结果:three one two

7,一个静态同步方法,一个非静态同步方法,两个number对象;结果:two one

8,两个静态同步方法,两个number对象;结果;three one two

  线程8锁的关键:

a:非静态的锁默认为this,静态的默认为Class对应的实例,所以静态的方法和非静态的方法没有竞争关系

b:某一时刻,只能有一个线程持有锁,无论几个方法

public class Thread8Monitor {    public static void main(String[] args) {        final Thread8 thread8 = new Thread8();        final Thread8 thread81 = new Thread8();        new Thread(new Runnable() {            @Override            public void run() {                thread8.getOne();            }        },"getOne").start();        new Thread(new Runnable() {            @Override            public void run() {                thread81.getTwo();            }        },"getOne").start();        new Thread(new Runnable() {            @Override            public void run() {                thread8.getThree();            }        },"getThree").start();    }}
public class Thread8 {    public static synchronized void getOne(){            try {                Thread.sleep(8000);            } catch (InterruptedException e) {            }        System.out.println("one");    }    public static synchronized void getTwo(){        System.out.println("two");    }    public  void getThree(){        System.out.println("three");    }}
九,线程池


一,线程池:提供了一个线程队列,队列中保存着所有等待状态的线程.避免了创建和销毁额外开销,提高了相应的速度.

二,线程池的体系结构:

java.util.concurrent.Executor:负责线程的使用与调度的根接口

|--**ExecutorService 子接口:线程池的主要接口

    |--**ThreadPoolExecutor 线程池的实现类

    |--**ScheduledExecutorService 子接口:负责线程的调度

        |--**ScheduledThreadPoolExecutor 继承ThreadPoolExecutor 实现ScheduledExecutorService 

三,工具类:Executor

ExecutorService newFixedThreadPool()创建固定大小的线程池,需要自己设定其大小;

ExecutorService newCacheTreadPool()创建缓存线程池,线程数量随着需要变化;

ExecutorService newSingleThreadExecutor()创建唯一线程的线程池

ScheduledExecutorService  newScheduledThreadPool()创建固定大小的线程池,可以延时或执行定时任务

/*使用工具类Executors*/public class ThreadPool {    public static void main(String[] args) throws ExecutionException, InterruptedException {        //Runnable接口        ThreadPoolTest threadPoolTest = new ThreadPoolTest();        //创建线程        ExecutorService threadFixed = Executors.newFixedThreadPool(5);       ExecutorService cachedThreadPool = Executors.newCachedThreadPool();        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);        for (int i = 0; i <20 ; i++) {                //为线程分配任务                threadFixed.submit(threadPoolTest);//                cachedThreadPool.submit(threadPoolTest);//                singleThreadExecutor.submit(threadPoolTest);//                scheduledExecutorService.submit(threadPoolTest);        }        //关闭线程池        threadFixed.shutdown();      }}
public class ThreadPoolTest implements Runnable{    @Override    public void run() {        int sum=0;        for (int i = 0; i <= 100; i++) {            sum+=i;        }        System.out.println(Thread.currentThread().getName()+" : "+sum);    }}
/*使用工具类Executors*/public class ThreadPool {    public static void main(String[] args) throws ExecutionException, InterruptedException {        //创建线程        ExecutorService threadFixed = Executors.newFixedThreadPool(10);        List<Future> list = new ArrayList<Future>();        //callabole接口        for (int i = 0; i < 10; i++) {            Future<Integer> future=threadFixed.submit(new Callable() {                @Override                public Integer call() throws Exception {                    int sum=0;                    for (int i = 0; i < 10; i++) {                        sum+=i;                    }                    return sum;                }            });            list.add(future);        }        //关闭线程        threadFixed.shutdown();        for (int i = 0; i < list.size(); i++) {            System.out.println(Thread.currentThread().getName()+list.get(i).get());        }    }}
  //③线程池调度(定时任务)//创建线程池ScheduledExecutorService scheduledExecutorPool = Executors.newScheduledThreadPool(5);List<Future> list1 = new ArrayList<Future>();for (int i = 0; i < 10; i++) {    Future<Integer> future = scheduledExecutorPool.schedule(new Callable<Integer>() {        @Override        public Integer call() throws Exception {            int sum = 0;            for (int i = 0; i < 10; i++) {                sum += i;            }            return sum;        }    }, 1, TimeUnit.SECONDS);    list1.add(future);}scheduledExecutorPool.shutdown();for (int i = 0; i < list1.size(); i++) {    System.out.println(Thread.currentThread().getName()+" : "+list1.get(i).get());}

十,Fork/join框架

在必要的情况下,将一个大任务分割(fork)为很多个小任务,分割标准按自定义的临街值进行,然后将运算结果汇总(join)到一起,达到提高效率的目的,

import java.util.concurrent.RecursiveTask;/** * Created by 13795 on 2017/9/20. */public class ForkAndJoinDemo extends RecursiveTask<Long>{    private long start;    private long end;    private static final long THURSHOLD=10000000L;//临界值    public ForkAndJoinDemo(long start, long end) {        this.end = end;        this.start = start;    }    @Override    protected Long compute() {        long length=end-start;        if (length < THURSHOLD) {            long sum = 0;            for (long i = start; i <= end; i++) {                sum += i;            }            return sum;        } else {            long middle=(start+end)/2;            ForkAndJoinDemo forkAndJoinDemoLeft = new ForkAndJoinDemo(start, middle);            forkAndJoinDemoLeft.fork();            ForkAndJoinDemo forkAndJoinDemoRight = new ForkAndJoinDemo(middle + 1, end);            forkAndJoinDemoRight.fork();            return forkAndJoinDemoLeft.join() + forkAndJoinDemoRight.join();        }    }}
import java.time.Duration;import java.time.Instant;import java.util.concurrent.ForkJoinPool;/** * Created by 13795 on 2017/9/20. */public class ForkAndJoinTest {    public static void main(String[] args) {        Instant startTime = Instant.now();        ForkJoinPool forkJoinPool = new ForkJoinPool();        ForkAndJoinDemo forkAndJoinDemo = new ForkAndJoinDemo(0L,5000000000L);        Long invoke = forkJoinPool.invoke(forkAndJoinDemo);        System.out.println(invoke);        Instant startEnd = Instant.now();        long timeLong = Duration.between(startTime, startEnd).toMillis();        System.out.println("耗时为"+timeLong);        /*        * -4378596987249509888            耗时为49565*/    }    @Test    public void sum() {        Instant startTime = Instant.now();        long sum=0;        for (long i = 0L; i <5000000000L; i++) {            sum += i;        }        Instant startEnd = Instant.now();        long timeLong = Duration.between(startTime, startEnd).toMillis();        System.out.println(sum);        System.out.println("耗时为"+timeLong);        /**         * 124999999750000000         耗时为613         */    }}


















原创粉丝点击