zoukankan      html  css  js  c++  java
  • 线程

    date: 2015-09-05 13:36:48


    Thread

    最近在写一个聊天室程序(task),两年多没碰java了,还是有点生疏
    线程,亮点是线程的异步并发执行,难点是线程的同步,理解并且控制好线程,very funny
    Thread系列分为1,2两个部分,分别讲控制和关闭的一些个人认识.
    以下为,Thread_part1,内容为线程控制:

    问题:利用Java多线程,轮流打印数字.
    三种方法:

    1. 利用synchronized关键字
    	//定义一个static final对象
        private static final ThreadTest lock = new ThreadTest();
        @Override
        public void run() {
            while (n < 100) {
                synchronized (lock) { //锁住对象实现线程同步
                    while ((n % 5 == 0) && (n / 5) % 5 != id) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    if (n < 100) {
                        System.out.print("Thread-" + (id+1) + " : " + " " + (n + 1)
                                + " " + (n + 2) + " " + (n + 3) + " " + (n + 4)
                                + " " + (n + 5) + "
    ");
                        n += 5;
                    }
                    lock.notifyAll();
                }
            }
        }
    
    1. 通过AtomicInteger对象,和ExecutorService实现线程之间的同步
        private AtomicInteger atomicInteger=new AtomicInteger(0);
        private static final int max=20;
        class Thread1 implements Runnable{
            private int mark=0;
            public Thread1(int i){
                this.mark=i;
            }            
            public void run() {
                while(atomicInteger.get()<max){//ACID的特性保证了同步
                    if(atomicInteger.get()%5==mark){
                        System.out.println("线程Thread"+(mark+1)+"打印:"+(atomicInteger.get()*5+1)+" "
                                        +(atomicInteger.get()*5+2)+" "+(atomicInteger.get()*5+3)+" "
                                        +(atomicInteger.get()*5+4)+" "+(atomicInteger.get()*5+5));
                        atomicInteger.getAndIncrement();//AtomicInteger的ACID自增方法
                    }
                }
            }
        }
    
    1. 通过ReentrantLock对象和Condition对象实现线程之间的同步
        private  int state = 1;
        private  int n = 1;    
        private ReentrantLock lock=new ReentrantLock();
        private Condition condition1=lock.newCondition();
        private Condition condition2=lock.newCondition();
        private Condition condition3=lock.newCondition();
        @Override
        public void run(){
            new Thread(new Runnable() {            
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    for (int i = 0; i < 5; i++) {
                        try {
                            lock.lock();
                            while(state!=1)
                                try{
                                    condition1.await();
                                }
                            catch (InterruptedException e) {
                                // TODO: handle exception
                                e.printStackTrace();
                            }
                            System.out.print(Thread.currentThread().getName()+": ");
                            for (int j = 0; j < 5; j++) {
                                System.out.print(n+++" ");
                            }
                            System.out.println();    
                            state=2;
                            condition2.signal();
                        } finally{
                            lock.unlock();
                        }
                    }
                }
            },"线程1").start();
    		new Thread(同上,state=3;condition3.signal;.....).start();
    		new Thread(同上,state=1;condition1.signal; .....).start();
    

    date: 2015-09-05 14:05:40


    问题:一个线程,让他一直运行在主程序运行期间,如何安全有效的关闭线程?
    常用做法:

    while(flag)
    {
    XXX//do something....
    }
    void close(){
    this.flag=false;
    }
    

    通过这种主动标志,有时候可以让线程停止。但是如果,在XXX处出现让线程阻塞的情况,显然close()方法无法关闭线程,而且会造成线程的阻塞。
    比如,XXX可能是,A=B.accept();
    假如B没有accept到A,那么线程就会阻塞在这个地方
    So
    解决方案:

    void close(){
    this.flag=false;
    new A(XXX);//此处应是任何可以使线程运行下去的方法,保证线程运行到while-loop对flag的判断
    }
    

    当然在实现程序中,要比这复杂,但是基本思路是这样,欢迎批评指正!



    I am a slow walker, but I never walk backwards.



  • 相关阅读:
    python 迭代器&&生成器
    windows 10 扩大C盘空间
    robot framework 接口自动化测试和关键字开发
    Robot framework 环境搭建+图标处理
    Docker 安装-在centos7下安装Docker(二)
    win10系统rational rose 安装后打开弹框显示java.lang.ClassNotFoundException 解决方案
    mysql 关系表 分组读取的方法
    关于浮点型计算遇到的小问题
    dom 的介绍
    网站前端相关的知识点
  • 原文地址:https://www.cnblogs.com/lknny/p/5648434.html
Copyright © 2011-2022 走看看