线程

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");
                    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的判断
}

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

posted @ 2016-07-06 23:16  toto怎么会喝醉  阅读(117)  评论(0编辑  收藏  举报