码迷,mamicode.com
首页 > 编程语言 > 详细

线程知识总结

时间:2015-08-26 13:47:58      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:

实现线程有两种方法,一种是实现runnable接口,一种是继承Thread线程类。关于这两者的区别是前者只是实现了runnable接口的一个类而已并不是线程,后者继承Thread才是线程

我们来看看代码具体了解下

public class ThreadTest {
		public static void main(String[] args) {
			T1 t1=new T1("t1");
			T2 t2=new T2("t2");
			new Thread(t1).start();//1语句 从测试代码可以看t2才是一个真正意义上的线程对象而t1不是
			t2.start();//2语句  这里值得注意的是语句1没执行完时 语句2就开始执行了语句1和语句2时并发执行的
		}


	}
	class T1 implements Runnable {
		String name;
		public T1(String name) {
			this.name = name;
		}
		public void run() {
			for(int i=0;i<5;i++){
				System.out.println("i am "+name);
			}
		}

	}
	class T2 extends Thread {
		String name;
		public T2(String name) {
		
			this.name = name;
		}
		public void run() {
			
			for(int i=0;i<5;i++){
				System.out.println("i am "+name);
			}
		}
	}

 

有了线程我们可以并发处理,但这在一定程度上也会让出现读取脏数据,或者说丢失更新,数据混乱等情况的发生,例如单例模式中两线程同时访问公共单例获取方法 一线程准备给对象引用赋值时,一线程却读取对象的引用为空,也准备创建对象,并把引用赋予局部变量。

这样一来就造成单例对象数据混乱,出现两个实例,和我们的本意相违背。

为了同步,我们引入了synchronized关键字来同步。synchronized关键字既可以用于对象前,也可以用于方法修饰。synchronized(对象引用名) public synchronized void(){}

synchronized关键字保证资源的互斥性,即一段时间之类只能有一个线程访问。线程访问之前必须持有资源锁才能访问。

线程同步简单口述下,就不发代码了。下面我们来看下线程协作。

这里要用到关键字wait() notify() 方法 线程协作我们来看看经典代码生产者 消费者

public class Cooperation {
		public static void main(String[] args) {
			SuperMonitor monitor = new SuperMonitor();
			new Producer(monitor,200);
			new Consumer(monitor,200);
			
			
			try
			{
				Thread.sleep(1000);	
			}
			catch (InterruptedException e) {
					e.printStackTrace();
			}

		}
	}
	//生产 消费要平衡 生产后再消费,消费完后再生产 由管理员类控制
	class  SuperMonitor {
		boolean valueSet = false;//标志是否在生产
		int count;//生产的物品总量
		public SuperMonitor() {
		
		}
		public synchronized int get() {
			if(!valueSet) {//生产线程不再生产了,那么消费线程进入等待池,等待生产线程唤醒
				
				try{
					wait();
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
		
			}
			
			valueSet = false;
			System.out.println("已消费"+count+"产品");
			notify();
			return count;
		}
		public synchronized void set(int i) {
		
			if(valueSet) {//如何生产线程可以生产了,生产线程进入等待池,等待消费线程唤醒
			
				try{
					wait();
				}
				catch (InterruptedException e) {
					//e.printStackTrace();
				}
			}

			valueSet = true;
			count=i;
			System.out.println("已生产"+count+"产品");
			notify();
		
	   }
	 }
	   class Producer implements Runnable{
			SuperMonitor monitor;
			int speed;//生产速度相关系数
			
		    public Producer(SuperMonitor monitor,int speed) {
				this.monitor = monitor;
				this.speed = speed;
				new Thread(this,"Producer").start();
			}
			
			public void run() {
				int i=0;
				while(true){
					monitor.set(++i);
					try
					{
						Thread.sleep((int)Math.random()*speed);	
					}
					catch (InterruptedException e) {
					//e.printStackTrace();
					}
				}
			
			}
			
	   }
	   class Consumer implements Runnable{
		   SuperMonitor monitor;
		   int speed;//消费数量相关系数
		  
			public Consumer(SuperMonitor monitor,int speed) {
				this.monitor = monitor;
				this.speed = speed;
				new Thread(this,"Consumer").start();
			}
			
			public void run() {
				while(true) {
					monitor.get();
					
				try
			    {
					Thread.sleep((int)Math.random()*speed);	
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		 }
	   }

 

这里指的注意的是管理员类里get set 方法需要加锁因为多线程环境下可能找造成同时调用方法,否则会造成异常

 

 

线程知识总结

标签:

原文地址:http://www.cnblogs.com/kimoyoyo21/p/4760063.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!