java多线程基础部分探究

1.多线程实现方式

1.继承Thread类,但是对于单继承的Java,限制很大

2.实现Runnable接口


public class DemoThread {


				public static void main(String[] args) {
					Play play = new Play();
					Thread thread = new Thread(play);
					thread.start();
				}
				
			}


			class Play implements Runnable{


				@Override
				public void run() {
					// TODO Auto-generated method stub
					for(int i = 0; i<10;i++){
						System.out.println("线程:"+i);
						try {
							Thread.sleep(2000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					System.out.println();
				}
			}


3.使用Timer和TimerTask组合

最后一种实现多线程的方式,就是使用java.util包中的Timer和TimerTask类实现多线程,使用这种方式也可以比较方便的实现线程。
在这种实现方式中,Timer类实现的是类似闹钟的功能,也就是定时或者每隔一定时间触发一次线程。其实,Timer类本身实现的就是一个线程,
只是这个线程是用来实现调用其它线程的。而TimerTask类是一个抽象类,该类实现了Runnable接口,所以按照前面的介绍,该类具备多线程的能力。
在这种实现方式中,通过继承TimerTask使该类获得多线程的能力,将需要多线程执行的代码书写在run方法内部,然后通过Timer类启动线程的执行。
在实际使用时,一个Timer可以启动任意多个TimerTask实现的线程,但是多个线程之间会存在阻塞。所以如果多个线程之间如果需要完全独立运行的话,
最好还是一个Timer启动一个TimerTask实现。

public class DemoTimerMark {


					public static void main(String[] args) {
						Timer timer1 = new Timer();
						Timer timer2 = new Timer();
						MyTimerTask task1 = new MyTimerTask(1);
						timer1.schedule(task1, 1000);
						MyTimerTask task2 = new MyTimerTask(2);
						timer2.schedule(task2, 1000);
						
					}
				}


				class MyTimerTask extends TimerTask{


					private int count;
					public MyTimerTask(int i){
						this.count = i;
					}
					@Override
					public void run() {
						// TODO Auto-generated method stub
						for(int i = 0; i<4;i++){
							System.out.println("线程"+this.count+":"+i);
							try {
								Thread.sleep(2000);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						System.out.println("========================================END=====================================");
					}
					
				}
				//

2,线程状态

1.新生状态 new
2.被阻塞状态 blocked
3.可运行状态 runnable
4.等待 waiting
5.计时等待 time waiting
6.被终止 terminated

3.线程细节

1.线程优先级
setPriority方法可以为线程设置优先级 ,优先级默认继承父线程的优先级 ,线程优先级高度依赖于操作系统。Java线程优先级会被映射到寄主主体平台的优先级上面
2.守护线程 setDaemon(true)
为其他线程提供服务的线程。如计时器线程。当只有一个守护线程时,虚拟机会退出(守护线程永远不要去访问固件资源,因为他会随时中断)

4.锁   方法一:Lock/Condition  方法二:synchronized

1.条件对象
一个锁可以有多个条件,每个条件上可以有多个线程等待,通过调用await()方法,可以让线程在该条件下等待。当调用signalAll()方法,又可以唤醒该条件下的等待的线程。
有关Condition接口的API可以具体参考JavaAPI文档。
2.synchronized 用此关键词声明的方法必须要获得程序的内部锁

3.同步阻塞 使用一个对象的锁来实现额外的原子操作称为 客户端锁定


5,银行取款问题

		// 银行取款问题
		// 不加锁
			public class BankProblem {
	
				public static void main(String[] args) {
					Bank bank = new Bank();
					for(int i=0;i<1000;i++){
						Transable transable = new Transable(bank,i);
						Thread thread =new Thread(transable);
						thread.start();
					}
				}
			}
			class Bank{
				private int[] count = new int[10];
				public Bank(){
					for(int i=0;i<10;i++){
						this.count[i] = 1000;
					}
				}
				public  void  trans(String name,int from,int to,int n) throws InterruptedException{
					if(count[from]>n){
						count[from]-=n;
						System.out.print("");
						count[to]+=n;
						System.out.println(name+" : 用户"+from+"向用户"+to+"转入:"+n+"   目前总资金为:"+this.toString());
					}
				}
				@Override
				public String toString() {
					// TODO Auto-generated method stub
					int out = 0;
					for(int i:count)
						out+=i;
					return out+"";
				}
				public int[] getCount() {
					return count;
				}

				public void setCount(int[] count) {
					this.count = count;
				}
			}
			class Transable implements Runnable{


				private Bank bank;
				private int i;
				public Transable(Bank bank,int i){
					this.bank = bank;
					this.i = i;
				}
				@Override
				public void run() {
					// TODO Auto-generated method stub
					while(true){
						try {
							bank.trans("线程"+i, RandomUtils.nextInt(10), RandomUtils.nextInt(10), RandomUtils.nextInt(1000));

						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
			
					}
				}
	
			}		

上述代码中会发生线程安全问题,对此有下面几个解决方案


	//=============================================================。
			解决方法一
			public synchronized void  trans(String name,int from,int to,int n) throws InterruptedException{
					if(count[from]>n){
						count[from]-=n;
						System.out.print("");
						count[to]+=n;
						System.out.println(name+" : 用户"+from+"向用户"+to+"转入:"+n+"   目前总资金为:"+this.toString());
					}
				}	
			// 方法二
				public  void  trans(String name,int from,int to,int n) throws InterruptedException{
						lock.lock();
						try{
						while(count[from]>n){
							count[from]-=n;
							System.out.print("");
							count[to]+=n;
							System.out.println(name+" : 用户"+from+"向用户"+to+"转入:"+n+"   目前总资金为:"+this.toString());
						}
						}finally{
							lock.unlock();
						}
					}				
				// 用条件对象改进 解决方法三
				// 测试时,为试着将n改为 2*n 由于条件对象,照样可以运行,但是几秒之后发生死锁问题
				public  void  trans(String name,int from,int to,int n) throws InterruptedException{
					lock.lock();
					try{
					while(count[from]<n)
						condition.await();
						count[from]-=n;
						System.out.print("");
						count[to]+=n;
						System.out.println(name+" : 用户"+from+"向用户"+to+"转入:"+n+"   目前总资金为:"+this.toString());
						condition.signalAll();
					}finally{
						lock.unlock();
					}
				}
				// 用synchronized 方法代替显式的锁,很方便,代码如下,与上面的代码功能一样  解决方法四
					public synchronized  void  trans(String name,int from,int to,int n) throws InterruptedException{
							while(count[from]<n)
								wait();
								count[from]-=n;
								System.out.print("");
								count[to]+=n;
								System.out.println(name+" : 用户"+from+"向用户"+to+"转入:"+n+"目前总资金为:"+this.toString());
								notifyAll();
					}
				// 前面3,4方法都有死锁。有一个解决方法是,给wait()一个时间限制,超时后,自动退出
				public  void  trans(String name,int from,int to,int n) throws InterruptedException{
						lock.lock();
						try{
						while(count[from]<n)
							if(!condition.await(100, TimeUnit.MILLISECONDS)){
								System.out.println("遇到死锁,此交易退出!!");
								return;
							}
							count[from]-=n;
							count[to]+=n;
							System.out.println(name+" : 用户"+from+"向用户"+to+"转入:"+n+"   目前总资金为:"+this.toString());
							condition.signalAll();
						}finally{
							lock.unlock();
						}
					}


6.阻塞队列

将线程安全等问题交给阻塞队列
	public class BlockingQueueTest {


				public static String src = "/usr/spring-framework-2.5.5_src";
				public static void main(String[] args) {
					BlockingQueue<File> queue = new ArrayBlockingQueue<File>(19999);
					new Thread(new Find(queue, src)).start();
					for(int i = 0;i<10;i++)
					new Thread(new search(queue, "volatile")).start();
				}
			}


			class Find implements Runnable{
				private BlockingQueue<File> queue;
				private String firstFileName;
				public Find(BlockingQueue<File> queue, String firstFileName) {
					super();
					this.queue = queue;
					this.firstFileName = firstFileName;
				}
				@Override
				public void run() {
					File file = new File(firstFileName);
					try {
						findFile(file);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
	
				private void findFile(File file) throws InterruptedException{
					if(file.isDirectory()){
						File[] f = file.listFiles();
						for(File tmp:f){
							findFile(tmp);
						}
					}else{
						if(!queue.offer(file, 1000, TimeUnit.MILLISECONDS))
							System.out.println("添加失败");
					}
				}
			}
			class search implements Runnable{
				private BlockingQueue<File> queue;
				private String keyWords;
				public search(BlockingQueue<File> queue, String keyWords) {
					super();
					this.queue = queue;
					this.keyWords = keyWords;
				}
				@Override
				public void run() {
					// TODO Auto-generated method stub
					boolean b = true;
					try {
						while(b){
						File f = queue.poll(1000, TimeUnit.MILLISECONDS);
						if(f==null){
							b = false;
						}else{
							Scanner in = new Scanner(f);
							int len = 0;
							String tmp = "";
							while(in.hasNext()){
								len++;
								tmp = in.nextLine();
								if(tmp.contains(keyWords)){
									System.out.println("文件名为:"+f.getName()+" 第"+len+"行 : ");
									System.out.println("			"+tmp);
								}
							}
						}
						queue.peek();
						}
					} catch (Exception e) {
						e.printStackTrace();
					}finally{
					}
				}
			}		


7.Future  封装一个有返回值的一部运行任务,相当于有返回值的Runnable

	//Callable 相当于一个带有参数的Runable


			public class FutureTest {


				public static String src = "/usr/spring-framework-2.5.5_src/src";
				public static String key = "class";
				public static void main(String[] args) throws InterruptedException, ExecutionException {
					FutureTask<Integer> futureTask = new  FutureTask<Integer>(new Find(new File(src), key));
					new Thread(futureTask).start();
					System.out.println("个数为:"+futureTask.get());
				}
			}
			class Find implements Callable<Integer>{
				private File firstFile;
				private String key;
				private int count;
				public Find(File file,String key) {
					super();
					this.firstFile = file;
					this.key = key;
				}
				private Integer findFile(File file) throws InterruptedException, ExecutionException{
					List<Future<Integer>> list = new ArrayList<Future<Integer>>();
					if(file.isDirectory()){
						File[] f = file.listFiles();
						for(File tmp:f){
							if(tmp.isDirectory()){
								FutureTask<Integer> futureTask = new  FutureTask<Integer>(new Find(tmp, key));
								list.add(futureTask);
								new Thread(futureTask).start();
							}else{
								if(search(tmp))
									count++;
							}
						}
					}else{
						if(search(file))
							count++;
					}
					for(Future<Integer> future:list){
						count+=future.get();
					}
					return count;
				}
				public boolean search(File f) {
					try {
						if(f==null){
							return false;
						}else{
							Scanner in = new Scanner(f);
							String tmp = "";
							while(in.hasNext()){
								tmp = in.nextLine();
								if(tmp.contains(key)){
									return true;
								}
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}finally{
					}
					return false;
				}
				@Override
				public Integer call() throws Exception {
					try {
						return findFile(firstFile);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					return null;
				}
			}



8,连接池

//简单使用连接池只需要将上面的代码修改下

				public class ThreadPoolTest {


					public static String src = "/usr/spring-framework-2.5.5_src/src";
					public static String key = "class";
					public static void main(String[] args) throws InterruptedException, ExecutionException {
				//		FutureTask<Integer> futureTask = new  FutureTask<Integer>(new FindByPool(new File(src), key));
				//		new Thread(futureTask).start();
				//		System.out.println("个数为:"+futureTask.get());
						ExecutorService service = Executors.newCachedThreadPool();
						Future<Integer> future = service.submit(new FindByPool(new File(src), key,service));
						System.out.println(future.get());
					}
				}
				class FindByPool implements Callable<Integer>{
					private File firstFile;
					private String key;
					private ExecutorService service;
					private int count;
					public FindByPool(File file, String key2, ExecutorService service) {
						// TODO Auto-generated constructor stub
						this.firstFile = file;
						this.key = key2;
						this.service =  service;
					}
					private Integer findFile(File file) throws InterruptedException, ExecutionException{
						List<Future<Integer>> list = new ArrayList<Future<Integer>>();
						if(file.isDirectory()){
							File[] f = file.listFiles();
							for(File tmp:f){
								if(tmp.isDirectory()){
									FindByPool pool = new FindByPool(tmp,key,service);
									list.add(service.submit(pool));
								}else{
									if(search(tmp))
										count++;
								}
							}
						}else{
							if(search(file))
								count++;
						}
						for(Future<Integer> future:list){
							count+=future.get();
						}
						return count;
					}
					public boolean search(File f) {
						try {
							if(f==null){
								return false;
							}else{
								Scanner in = new Scanner(f);
								String tmp = "";
								while(in.hasNext()){
									tmp = in.nextLine();
									if(tmp.contains(key)){
										return true;
									}
								}
							}
						} catch (Exception e) {
							e.printStackTrace();
						}finally{
						}
						return false;
					}
					@Override
					public Integer call() throws Exception {
						try {
							if(firstFile!=null)
							return findFile(firstFile);
							else return 0;
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						return 0;
					}
				}


上面就是简单使用Java多线程的部分,还有关于线程安全与高并发部分的内容没有写出来.尽快补上


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值