zoukankan      html  css  js  c++  java
  • Java多线程与并发库

    同步方式

    import javax.xml.stream.events.StartDocument;
    
    public class TestSynchronized {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            TestSynchronized test = new TestSynchronized();
            test.init();
        }
        
        void init() {
            final Outputer outputer = new Outputer();
            
            new Thread(new Runnable(){
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    while(true){
                        try {
                            Thread.sleep(10);
                        } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        outputer.Output("wangyuyuyuyuyuyuyuyu");
                    }
                    
                }
            }){
            }.start();
            
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    while(true){
                        try {
                            Thread.sleep(10);
                        } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        outputer.Output("zhouzhanzhaozhaozhaozhao");
                    }
                }
            }){
            }.start();
        }
        
        
        class Outputer{
            final static String lockKey = "lock";
            //定义输出函数
            //第一种方式,提供某个锁
            public void Output(String name){
                int len = name.length();
                synchronized (lockKey) {
                    for (int i = 0; i < len; i++){
                        System.out.print(name.charAt(i));
                    }
                    System.out.println();
                }
            }
            //第二种方式,锁住自己
            public void Output1(String name){
                int len = name.length();
                synchronized (this) { //也可以用Outputer.class
                    for (int i = 0; i < len; i++){
                        System.out.print(name.charAt(i));
                    }
                    System.out.println();
                }
            }
            //第三种方式,函数前面加关键字synchronized
            public synchronized void Output2(String name){
                int len = name.length();
                for (int i = 0; i < len; i++){
                    System.out.print(name.charAt(i));
                }
                System.out.println();
                    
                
            }
        }
    
    }
    View Code

    定时器Timer

    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TimerTest {
        public static void main(String[] args){
            new Timer().schedule(new TimerTask(){
    
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    System.out.println("boom");
                }
                
            }, 3000);
        }
    }
    View Code

    HashMap存储线程

    import java.util.HashMap;
    import java.util.Map;
    import java.util.Random;
    
    public class TestThreadMap {
        private static HashMap<Thread, Integer> map = new HashMap<Thread, Integer>();
        public static void main(String[] args) {
            //TestThreadMap testThreadMap = new TestThreadMap();
            for (int i = 0; i < 2; i++) {
                new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        int data = new Random().nextInt();
                        map.put(Thread.currentThread(), data);
                        new A().Get();
                        new B().Get();
                    }
                }){}.start();
                 
                
            }
        }
        static class A{
            public void Get(){
                int data = map.get(Thread.currentThread());
                System.out.println("A from " + Thread.currentThread().getName() + " get data " + data);
            }
        }
        
        static class B{
            public void Get(){
                int data = map.get(Thread.currentThread());
                System.out.println("B from " + Thread.currentThread().getName() + " get data " + data);
            }
        }
    }
    View Code

    ThreadLocal类似HashMap存储线程

    import java.util.HashMap;
    import java.util.Map;
    import java.util.Random;
    
    public class TestThreadMap {
        private static HashMap<Thread, Integer> map = new HashMap<Thread, Integer>();
        public static void main(String[] args) {
            //TestThreadMap testThreadMap = new TestThreadMap();
            for (int i = 0; i < 2; i++) {
                new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        int data = new Random().nextInt();
                        map.put(Thread.currentThread(), data);
                        new A().Get();
                        new B().Get();
                    }
                }){}.start();
                 
                
            }
        }
        static class A{
            public void Get(){
                int data = map.get(Thread.currentThread());
                System.out.println("A from " + Thread.currentThread().getName() + " get data " + data);
            }
        }
        
        static class B{
            public void Get(){
                int data = map.get(Thread.currentThread());
                System.out.println("B from " + Thread.currentThread().getName() + " get data " + data);
            }
        }
    }
    View Code
    import java.util.Random;
    
    
    public class TestThreadlocal_2 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            for (int i = 0; i < 2; i++){
                new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        int data = new Random().nextInt();
                        MyData.getInstance().setName("myData" + data);
                        MyData.getInstance().setAge(data);
                        new A().Get();
                        new B().Get();
                    }
                }){}.start();
            }
    
        }
        
        static class A{
            public void Get(){
                MyData data = MyData.getInstance();
                System.out.println("A from " + Thread.currentThread().getName() + " get data " + data.getName() + ", " + data.getAge());
            }
        }
        static class B{
            public void Get(){
                MyData data = MyData.getInstance();
                System.out.println("B from " + Thread.currentThread().getName() + " get data " + data.getName() + ", " + data.getAge());
            }
        }
    
    }
    
    class MyData{
        String name;
        int age;
        
        public static /*synchronized*/ MyData getInstance(){
            MyData instance = threadLocal.get();
            if (instance == null){  //不存在就创建一个与本线程有关的实例对象
                instance = new MyData();
                threadLocal.set(instance);
                
            }
            return instance;
        }
        
        //private static MyData instance = null;
        private static ThreadLocal<MyData> threadLocal = new ThreadLocal<MyData>();
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
    }
    View Code

    线程池

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    public class TestThreadPool {
        public static void main(String[] args){
            //固定大小的线程池
            ExecutorService threadPool = Executors.newFixedThreadPool(3);
            //缓存线程池,当线程不够用时会自动增加,多了会自动减少
            //ExecutorService threadPool = Executors.newCachedThreadPool();
            //单一线程池,线程死了可以重新启动
            //ExecutorService threadPool = Executors.newSingleThreadExecutor();
            for (int i = 1; i <= 10; i++){
                final int taskid = i;
                threadPool.execute(new Runnable() {
                    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        for (int j = 1; j <= 10; j++) {
                            System.out.println(Thread.currentThread().getName() + " is loop of " + j + " for task of " + taskid);
                        }
                    }
                });
            }
            System.out.println("all have finished");
            threadPool.shutdown(); //线程池里没有任务了,线程池才关闭,等10个任务都完成后才关闭
            //threadPool.shutdownNow(); //一个线程完成之后立马关闭,此时只完成了3个任务
            
            /*//定时器线程池
            Executors.newScheduledThreadPool(3).schedule(
                    new Runnable() {
                        
                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            System.out.println("booming");
                        }
                    }, 
                    6,
                    TimeUnit.SECONDS); //多长时间后执行任务
    */        
            Executors.newScheduledThreadPool(3).scheduleAtFixedRate( //以固定频率执行任务
                    new Runnable() {
                        
                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            System.out.println("booming");
                        }
                    }, 
                    6,  //初始时间
                    2,  //间隔时间
                    TimeUnit.SECONDS);
            
            
        }
    }
    View Code

    锁Lock

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    import javax.xml.stream.events.StartDocument;
    
    public class TestLock {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            TestLock test = new TestLock();
            test.init();
        }
        
        void init() {
            final Outputer outputer = new Outputer();
            
            new Thread(new Runnable(){
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    while(true){
                        try {
                            Thread.sleep(10);
                        } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        outputer.Output("wangyuyuyuyuyuyuyuyu");
                    }
                    
                }
            }){
            }.start();
            
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    while(true){
                        try {
                            Thread.sleep(10);
                        } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        outputer.Output("zhouzhanzhaozhaozhaozhao");
                    }
                }
            }){
            }.start();
        }
        
        
        class Outputer{
            Lock lock = new ReentrantLock(); //
            public void Output(String name){
                int len = name.length();
                
                lock.lock();
                try {
                    
                    for (int i = 0; i < len; i++){
                        
                        System.out.print(name.charAt(i));
                    }
                    System.out.println("");
                } finally{
                    // TODO: handle exception
                    lock.unlock();
    
                }
            }
            
        }
    
    }
    View Code

    读写锁ReadWriterLock

    import java.util.HashMap;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class TestReadWriterLock {
        HashMap<String, Object> mp = new HashMap<String, Object>();
        private ReadWriteLock rwl = new ReentrantReadWriteLock();
        public Object Get(String key){
            rwl.readLock().lock();
            Object value = null;
            try {
                value = mp.get(key);
                if (value == null) {
                    rwl.readLock().unlock();
                    rwl.writeLock().lock();
                    try {
                        if (value == null){
                            value = "aaa";
                        }
                        
                    } finally {
                        // TODO: handle finally clause
                        rwl.writeLock().unlock();
                    }
                    rwl.readLock().lock();
                }
            } finally {
                rwl.readLock().unlock();
            }
            return value;
        }
    }
    View Code

    信号灯Semaphere(控制当前运行的线程个数)

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    import java.util.function.IntToDoubleFunction;
    
    public class TestSemaphere {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            /*1.创建线程池
             *2.创建信号灯,大小为3 
             *3.循环10次,Runnable里设置信号灯acqure
             */
            
            ExecutorService es = Executors.newCachedThreadPool();
            Semaphore semaphore = new Semaphore(3);
            for(int i = 0; i < 10; i++){
                es.execute(new Runnable() {
                    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
                            semaphore.acquire();
                        } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        
                        System.out.println("线程" + Thread.currentThread().getName() + "进入");
                        try {
                            Thread.sleep((int)Math.random() * 10000);
                        } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        System.out.println("线程" + Thread.currentThread().getName() + "即将结束");
                        semaphore.release();
                        System.out.println("线程" + Thread.currentThread().getName() + "已结束");
                        es.shutdown();
                        
                    }
                });
            }
        }
    
    }
    View Code

    数据交换Exchanger(当两个数据都到达后才能进行交换,否则阻塞)

    import java.util.concurrent.Exchanger;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class TestExchanger {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            ExecutorService es = Executors.newCachedThreadPool();
            Exchanger<String> exchanger = new Exchanger<String>();
            es.execute(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        String data1 = "x";
                        System.out.println("线程" + Thread.currentThread().getName() + "正在把数据" + data1 + "发送出去");
                        Thread.sleep((int)(Math.random() * 5000));
                        String getData = exchanger.exchange(data1);
                        System.out.println("线程" + Thread.currentThread().getName() + "接受到的数据为: " + getData);
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                    }
                }
            });
            
            es.execute(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        String data1 = "y";
                        System.out.println("线程" + Thread.currentThread().getName() + "正在把数据" + data1 + "发送出去");
                        Thread.sleep((int)(Math.random() * 5000));
                        String getData = exchanger.exchange(data1);
                        System.out.println("线程" + Thread.currentThread().getName() + "接受到的数据为: " + getData);
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                    }
                }
            });
        }
    
    }
    View Code

    同步屏障CyclicBarrier(多个线程彼此等待,集合后再往后运行)

    import java.util.concurrent.CyclicBarrier;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class TestCyclicBarrier {
        //多个线程彼此等待,集合后再运行
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //创建线程池和CyclicBarrier,同时运行多个线程,调用await
            
            ExecutorService es = Executors.newCachedThreadPool();
            final CyclicBarrier cb = new CyclicBarrier(3);
            for (int i = 0; i < 3; i++){
                es.execute(new Runnable() {
                    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
                            Thread.sleep((int)(Math.random() * 1000));
                            System.out.println("线程" + Thread.currentThread().getName() + "到达集合点1");
                            System.out.println("当前有" + (cb.getNumberWaiting()+1) + "人在等待");
                            cb.await();
                            Thread.sleep((int)(Math.random() * 1000));
                            System.out.println("线程" + Thread.currentThread().getName() + "到达集合点2");
                            System.out.println("当前有" + (cb.getNumberWaiting()+1) + "人在等待");
                            cb.await();
                            Thread.sleep((int)(Math.random() * 1000));
                            System.out.println("线程" + Thread.currentThread().getName() + "到达集合点3");
                            System.out.println("当前有" + (cb.getNumberWaiting()+1) + "人在等待");
                            cb.await();
                            
                        } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        
                    }
                });
            }
            es.shutdown();
    
        }
    
    }
    View Code

    CountDownLatch(类似倒计时计数器,当计数减为0时,所有等待者才开始执行)

    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class TestCountDownLatch {
        //类似倒计时计数器,当计数减为0的时候,所有等待者才开始执行
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //创建两个计数器,一个为1,一个为3,代表一个裁判员,三个运动员,裁判员在未下达命令前运动员等待,下达命令后才执行
            //等三个运动员都到达终点后,裁判员才公布成绩
            ExecutorService es = Executors.newCachedThreadPool();
            CountDownLatch cdOrder = new CountDownLatch(1);
            CountDownLatch cdAnswer = new CountDownLatch(3);
            for (int i = 0; i < 3; i++) {
                final int id = i;
                es.execute(new Runnable() {
                    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
                            System.out.println("运动员" + id + "正准备接受命令");
                            cdOrder.await();
                            System.out.println("运动员"+ id + "接受到命令");
                            Thread.sleep((int)(Math.random() * 5000));
                            System.out.println("运动员" + id + "到达终点");
                            cdAnswer.countDown();
                            
                        } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        
                        
                    }
                });
            }
            
            try {
                Thread.sleep(1000);
                System.out.println("裁判员发出指令");
                cdOrder.countDown();
                System.out.println("裁判员等待所有运动员到达终点");
                cdAnswer.await();
                System.out.println("裁判员公布成绩");
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    
    }
    View Code

    Callable和Future

    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class TestCallableAndFuture {
        public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException{
            ExecutorService threadPool = Executors.newSingleThreadExecutor();
            Future future =
                    threadPool.submit(new Callable<String>() {
                        @Override
                        public String call() throws Exception {
                            // TODO Auto-generated method stub
                            Thread.sleep(2000);
                            return "hello";
                        }
                    });
            
            System.out.println("得到结果: " + future.get()); //callable完成任务返回结果,由future去拿,需要等待一段时间
            //System.out.println("得到结果: " + future.get(1, TimeUnit.SECONDS)); //要在规定的时间内得到结果,如果得不到就抛出异常
            
            //CompletionService 用于提交一组callable任务,并用take方法得到一个已完成任务的future对象
            ExecutorService threadPool2 = Executors.newFixedThreadPool(10);
            CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
            
            for (int i = 1; i <= 10; i++){
                final int taskid = i;
            completionService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    // TODO Auto-generated method stub
                    try {
                        Thread.sleep(new Random().nextInt(5000));
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                    return taskid;
                }
            });
            }
            
            for (int i = 1; i <= 10; i++){
                System.out.println(completionService.take().get());
            }
        }
    
    }
    View Code

    阻塞队列ArrayBlockingQueue

    import java.util.concurrent.ArrayBlockingQueue;
    
    public class TestArrayBlockingQueue {
        //阻塞队列当队列为空时take会阻塞,当队列满时put会阻塞
        //用两个阻塞队列模拟两个线程交替运行
        //两个阻塞队列大小均设置为1,其中一个放一个数据
        
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Business business = new Business();
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    for (int j = 1; j <= 10; j++) {
                        business.Sub(j);
                    }
                }
            }){}.start();
            
            for (int j = 1; j <= 10; j++) {
                business.Main(j);
            }
            
        }
        
        static class Business{
            ArrayBlockingQueue abq1 = new ArrayBlockingQueue(1);
            ArrayBlockingQueue abq2 = new ArrayBlockingQueue(1);
            public Business() 
            {
                try {
                    abq2.put(1);
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
            public void Sub(int j){
                try {
                    abq1.put(1);
                    for (int i = 1; i <= 10; i++){
                        System.out.println("sub thread " + i + " of loop " + j);
                    }
                    abq2.take();
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
                
            }
            
            public void Main(int j){
                try {
                    abq2.put(1);
                    for (int i = 1; i <= 10; i++){
                        System.out.println("main thread " + i + " of loop " + j);
                    }
                    abq1.take();
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
        }
    
    }
    View Code

    练习: 子线程运行10次,主线程运行20次,交替运行

    public class prictice_1 {
        //子线程运行10次,主线程运行20次
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Business business = new Business();
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    for (int j = 1; j <= 10; j++) {
                        business.Sub(j);
                    }
                }
            }){}.start();
            
            for (int j = 1; j <= 10; j++) {
                business.Main(j);
            }
        }
        
    
    }
    class Business{
        private boolean isSub = true;
        public synchronized void Sub(int j){
            while (!isSub) {
                try {
                    this.wait();
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
            for (int i = 1; i <= 10; i++){
                System.out.println("sub thread " + i + " of loop " + j);
            }
            isSub = false;
            this.notify();
        }
        
        public synchronized void Main(int j){
            while (isSub){
                try {
                    this.wait();
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
            for (int i = 1; i <= 20; i++){
                System.out.println("main thread " + i + " of loop " + j);
            }
            isSub = true;
            this.notify();
        }
    }
    View Code
  • 相关阅读:
    打开XX.etl文件
    ubuntu 安装 openssh-server,xinetd,vmware tools
    ESXi时间同步
    常用正则表达式字符说明
    RPC 服务器不可用
    linux 常用命令
    解决RDP连接不上
    python数据持久存储-pickle模块
    lambda表达式/对象引用计数
    关闭网络打开远程文件时防火墙安全弹窗
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/8456820.html
Copyright © 2011-2022 走看看