您的位置:首页 > 编程语言 > Java开发

java线程及操作实例,线程池简单例子

2014-10-27 13:28 801 查看
java io、集合、线程、字符串、gc、jvm可谓是java中的最基本的知识,尤其是线程操作复杂,相应难懂,要想java基础知识扎实,上面提到的几个方面的知识点都要精通,这样方可以称自己掌握java方面基础知识。

总结一下java线程知识,平时接触过线程,尤其是在android开发中,线程可谓是无处不在,稍有不注意就会报错。在java中线程也是无处不在,main就是一个线程,只不过被包装好了,一般接触不到。

我的无数次的复习经历告诉我,学习知识最快,最深刻的方法就是从解题开始,不要先看概念,遇到新知识点,新概念先自己用已有的原始知识解一遍,然后再去看相关解释,会发现,概念是那么的浅显易懂。废话不多说,先上题:

1.用两个线程,交叉输出“123...56”和“abc...z”,要求输出结果为“12a34b67c...5556z”。

分析:此题用到线程同步互斥的知识点。线程1输出->唤醒线程2->线程1等待,线程2输出->唤醒线程1->线程2等待...一直到输出完毕。本题几乎可以全面考察线程互斥的知识。有了这些分析就可以上代码:

/**
 * 
 * @author mxr
 *ClassName ThreadTest 
 *@Version 1.0
 *@ModifiedBy 2014-10-27
 *@Copyright RSDSYST
 */
public class ThreadTest extends Thread {

	 class Thread1 implements Runnable {
		 private Object _lock;

		 public Thread1(Object lock) {
		  _lock = lock;
		 }

		 @Override
		 public void run() {
		  try {
		   synchronized (_lock) {
		    for (int i = 0; i < 26; i++) {
		     System.out.print((2 * i + 1) + "" + (2 * i + 2));
		     _lock.notifyAll();//唤醒其他线程
		     _lock.wait();//释放锁,等待
		    }
		   }
		  } catch (InterruptedException e) {
		   e.printStackTrace();
		  }
		 }

		}

		 class Thread2 implements Runnable {
		 private Object _lock;

		 public Thread2(Object lock) {
		  _lock = lock;
		 }

		 @Override
		 public void run() {
		  synchronized (_lock) {
		   for (int i = 0; i < 26; i++) {
		    System.out.print((char) ('a' + i));
		    _lock.notifyAll();//叫醒其他线程
		    if(i<25){
		    	try {
					_lock.wait();//释放锁,等待
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		    }
		    
		   }
		  }
		 }

		}

		 public static void main(String[] args){
		  Object lock=new Object();
		  Thread t1=new Thread(new ThreadTest().new Thread1(lock));
		  Thread t2=new Thread(new ThreadTest().new Thread2(lock));
		  t1.start();
		  t2.start();
		  try {
		   t1.join();
		   t2.join();
		  } catch (InterruptedException e) {
		   e.printStackTrace();
		  }
		 }

}
上面的代码就是按照分析的思想去实现。上面的wait(),notifyAll()都只能用在同步代码块内。

2.用线程实现银行取钱问题,当出现错误时,如何进行同步。

/**
 * 
 * @author mxr
 *ClassName ThreadTest 
 *@Version 1.0
 *@ModifiedBy 2014-10-27
 *@Copyright RSDSYST
 */
class User{
	int sumCount = 100;
	User(){}
	public <span style="color:#ff0000;">synchronized</span> void  oper(int count){
		sumCount = sumCount - count;
		System.out.println(" has get: "+count+". the sumCount is: "+sumCount);
	}
}
public class ThreadTest extends Thread {
	User user;
	int useCount;
    ThreadTest(User user,int useCount){
    	this.user = user;
    	this.useCount = useCount;
    }
	public void run(){
		
			try {
				sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			user.oper(useCount);

	}

	 public static void main(String[] args){
		 System.out.println(Thread.currentThread().getName()+" is running");
		 User user = new User();
		 ThreadTest tt = new ThreadTest(user,30);
		 ThreadTest tt1 = new ThreadTest(user,20);
		 ThreadTest tt2 = new ThreadTest(user,30);
		 ThreadTest tt3 = new ThreadTest(user,10);
		 tt.start();
		 tt1.start();
		 tt2.start();
		 tt3.start();
		 System.out.println(Thread.currentThread().getName()+" is end");
	  
		 
	 }

}
代码如上,当在oper上不加synchronized时,出现的结果是错误的,因为在同一时间访问了money,加上同步之后,一个时刻只能有一个访问,所以避免了错误。

3.简单的对线程池的理解和应用。

线程池用ExecutorService和Executors来建立,为程序提供线程,当线程很多时,可以大大的节省内存空间,线程池是一个线程队列,当队列的容量小时,多出来的线程就会排队等待。

用容量为2的线程池来实现银行取款问题:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 
 * @author mxr
 *ClassName ThreadTest 
 *@Version 1.0
 *@ModifiedBy 2014-10-27
 *@Copyright RSDSYST
 */
class User{
	int sumCount = 100;
	User(){}
	public <span style="color:#ff0000;">synchronized</span> void  oper(int count){
		sumCount = sumCount - count;
		System.out.println(" has get: "+count+". the sumCount is: "+sumCount);
	}
}
public class ThreadTest extends Thread {
	User user;
	int useCount;
    ThreadTest(User user,int useCount){
    	this.user = user;
    	this.useCount = useCount;
    }
	public void run(){
		
			try {
				sleep(30);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			user.oper(useCount);

	}

	 public static void main(String[] args){
		 System.out.println(Thread.currentThread().getName()+" is running");
		 User user = new User();
		 ThreadTest tt = new ThreadTest(user,30);
		 ThreadTest tt1 = new ThreadTest(user,20);
		 ThreadTest tt2 = new ThreadTest(user,30);
		 ThreadTest tt3 = new ThreadTest(user,10);
		 ExecutorService pool = Executors.newFixedThreadPool(4);
		 pool.execute(tt);
		 pool.execute(tt1);
		 pool.execute(tt2);
		 pool.execute(tt3);
		 System.out.println(Thread.currentThread().getName()+" is end");
	  
		 
	 }

}
同样的,线程池自身是没有同步的,对共享块需要自己用synchronized来控制同步。

有一篇详细介绍java线程的专栏非常详细:http://lavasoft.blog.51cto.com/62575/27069/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: