线程
date: 2015-09-05 13:36:48
Thread
最近在写一个聊天室程序(task),两年多没碰java了,还是有点生疏
线程,亮点是线程的异步并发执行,难点是线程的同步,理解并且控制好线程,very funny!
Thread系列分为1,2两个部分,分别讲控制和关闭的一些个人认识.
以下为,Thread_part1,内容为线程控制:
问题:利用Java多线程,轮流打印数字.
三种方法:
- 利用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();
}
}
}
- 通过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自增方法
}
}
}
}
- 通过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.