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 */ }}
- java juc2
- java
- JAVA
- JAVA
- JAVA
- java
- Java
- Java
- JAVA:
- java
- java
- java
- java
- Java
- java
- java
- java
- JAVA?
- pg psql中切换current_user
- ext中的viewModel双向数据绑定皮毛
- Qt TableView的简单使用
- sql 创建聚集索引和非聚集索引
- Html和Css的一些笔记
- java juc2
- xml读取properties配置文件,web.xml读取properties,properties格式,properties在eclipse创建
- LoadCursor 加载不同的鼠标光标
- GitHub按钮功能
- Jquery的html方法里包含特殊字符的处理,类似双引号之类的
- hdu 6215 Brute Force Sorting 【链表+队列】
- PG update操作说明
- 如何定位虚拟机内部附加的数据磁盘
- 网络编程之编写LSP进行Winsock API监控拦截或LSP注入