`
uusoft
  • 浏览: 10609 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

多线程--札记

    博客分类:
  • j2se
 
阅读更多
1.什么是线程和进程?两者之间的关系?
进程是程序的一次动态执行过程,线程和进程都是实现并发的基本单位。
线程是比进程更小的执行单位,一个线程可以由多个线程组成,线程消亡了,进程还在,但进程消亡了,线程一定也随之消亡。

2.线程的创建有两种方法:继承Thread类和实现Runnable接口,其中继承Thread类受java单继承局限,实现Runnable接口更具灵活性,有利于功能扩展性和线程间的数据共享,如:Student类可以继承Person类同时实现Runnable。

 public class  ThreadStartDemo1
{
	public static void main(String[] args) 
	{
		MyThread my1=new MyThread("one");
		MyThread my2=new MyThread("two");
		my2.setName("TWO+++");
         my1.start();
	     my2.start();


	   for(int i=0;i<30;i++)
		{
			System.out.println("main----"+i);
		}

	}
}


class MyThread extends Thread
{
   //private String name;
   public MyThread(String name)
	{
	   super(name);
	}

	public void run()
	{
		for(int i=0;i<30;i++)
		{
			System.out.println(Thread.currentThread().getName()+"----"+i);
		}
	}
}


3.线程运行的五种状态
a.创建--继承Thread类和实现Runnable接口
b.就绪状态--调用start()方法后,线程有了执行的资格,等待获取cpu使用权
c.运行状态--线程有执行的资格且获得了cpu使用权
d.阻塞状态--I/O操作 wait() sleep()等导致阻塞,当阻塞条件解除重新回到就绪状态进行排队获取cpu执行权
e.死亡状态--stop()或者线程执行完毕

4.线程名字的设置、获取 setName getName()
静态方法Thread.currentThread()获取正在运行的线程


5.线程安全之(同步代码块和同步方法)
 
 /*银行一个小金库,由两个客户分别存3次钱,每次存100元,统计每次客户存钱后金库总额*/
 public class  BankDemo
{
	public static void main(String[] args) 
	{
		Cus c=new Cus();
		Thread t1=new Thread(c);
		Thread t2=new Thread(c);
		t1.start();
		t2.start();
	}
}
/*
//使用同步代码块的方法保障线程安全
class Bank
{
	private int sum=0;
	public void add(int n)
	{
		synchronized(this)
		{
			sum=sum+n;
			try
			{
				Thread.sleep(10);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			System.out.println("sum="+sum);
		}
	}
}
*/


//使用同步方法保障线程安全
class Bank
{
	private int sum=0;
	public synchronized void add(int n)
	{
		
			sum=sum+n;
			try
			{
				Thread.sleep(10);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			System.out.println("sum="+sum);
		
	}
}
class  Cus implements Runnable
{
	private Bank b=new Bank();
	public void run()
	{   for(int i=0;i<3;i++)
		{
		 b.add(100);  // 如果在此处进行同步的话,就是要等一个客户执行自己的全部操作次数才让另外一个客户进入操作,不符合实际
	    }
	}

}



6. 使用同步方法完成卖票程序

public class  TicketDemo
{
	public static void main(String[] args) 
	{
		MyThread my=new MyThread();
		Thread t1=new Thread(my);
		Thread t2=new Thread(my);
		Thread t3=new Thread(my);
		Thread t4=new Thread(my);
		
         t1.start();
	     t2.start();
		 t3.start();
		 t4.start();


	 

	}
}


class MyThread implements Runnable
{
   private  /*static */ int tic=30;

	public void run()
	{
		for(int i=0;i<300;i++)
		{   

			if(tic>0)
			{
			System.out.println("sale tickets:"+tic--);
			}
		}
	}
}




7.同步方法用static修饰后,用的锁不是this静态方法也不可以定义this,静态方法进入内存后,没有本类对象,而是有本类的的字节码对象所以静态同步方法锁的对象是  类名.class

 /*
   同步函数用的是哪一个锁呢?
   函数都要被对象调用,那么函数都有一个所属对象给引用,就是this
   验证同步函数的锁就是this
 
 */
 
 public class  ThisLockDemo1
{
	public static void main(String[] args) 
	{
		MyThread my=new MyThread();
		Thread t1=new Thread(my);
		Thread t2=new Thread(my);
	
		
         t1.start();
		 try{Thread.sleep(100); }catch(Exception e){ e.printStackTrace();}
		 my.flag=false;
	     t2.start();

	}
}


class MyThread implements Runnable
{
   private  int tic=30;
   boolean flag=true;
	public void run()
	{
		
	    //Object obj=new Object();
		if(flag)
		{
			 while(true)
			{
				  synchronized(this) //此处如果传入的参数是obj.那么输出数据将会错乱,因为多个线程间用的不是一个锁
				{
					if(tic>0)
				  {   
			
					try{Thread.sleep(100); }catch(Exception e){}
					System.out.println(Thread.currentThread().getName()+" sale @@@@@@:"+tic--);
		   
				   }
				}
			}
		}
		else
		{
			while(true)
			{
				this.take();
			}
		}
	}


	public synchronized void take()
	{
		if(tic>0)
			{   
				
				try{Thread.sleep(200); }
				catch(Exception e){}
			    System.out.println(Thread.currentThread().getName()+" take ######:"+tic--);
			   
			}
	}

}



public class  ThisLockDemo2
{
	public static void main(String[] args) 
	{
		MyThread my=new MyThread();
		Thread t1=new Thread(my);
		Thread t2=new Thread(my);
	
		
         t1.start();
		 try{Thread.sleep(100); }catch(Exception e){ e.printStackTrace();}
		 my.flag=false;
	     t2.start();

	}
}


class MyThread implements Runnable
{
   private  static int tic=30;
   boolean flag=true;
	public void run()
	{
		
	    //Object obj=new Object();
		if(flag)
		{
			 while(true)
			{
				  synchronized(MyThread.class) //此处如果传入的参数是obj.那么输出数据将会错乱,因为多个线程间用的不是一个锁
				{
					if(tic>0)
				  {   
			
					try{Thread.sleep(100); }catch(Exception e){}
					System.out.println(Thread.currentThread().getName()+" sale @@@@@@:"+tic--);
		   
				   }
				}
			}
		}
		else
		{
			while(true)
			{
				take();
			}
		}
	}


	public static synchronized void take()//同步方法用变为静态后,输出错误数据
	{
		if(tic>0)
			{   
				
				try{Thread.sleep(200); }
				catch(Exception e){}
			    System.out.println(Thread.currentThread().getName()+" take ######:"+tic--);
			   
			}
	}

}



8.单例模式之同步

//单例模式

//饿汉式
class Singleton
{
	private static final Singleton s=new Singleton();
    

	private Singleton(){} //将构造方法私有化
	public static Singleton getInstance()
	{
        return s;
	}
}


//懒汉式(延迟加载)
class Singleton
{
	private static Singleton s=null;
    private Singleton(){} //将构造方法私有化

    public static Singleton getInstance()
	{
		if(s==null)
		{   
			s=new Singleton();
			return s;
		}
	}
}



//懒汉式(延迟加载)
//被多线程访问时存在线程安全问题,所以可以采用同步方法
//保障线程安全,但这么做的缺点是,需要对锁反复进行判断,
//比较低效
class Singleton
{
	private static Singleton s=null;
    private Singleton(){} //将构造方法私有化

    public synchronized static Singleton getInstance()
	{
		if(s==null)
		{
			s=new Singleton();
		}
		return s;
	}
}



//双重判断 可以减少锁的判断 提高代码执行效率
class Singleton
{
	private static Singleton s=null;
    private Singleton(){} //将构造方法私有化

    public  static Singleton getInstance()
	{ 
	  if(s==null)
		  {
			  synchronized(Singleton.class)
				{
					if(s==null)
					{
						s=new Singleton();
					}
					
				}
	      }
	 return s;
	}
}

9.死锁

//1.死锁是程序都在等待对方先完成,在僵持不下的情况下,就会使程序的执行处于停滞状态
//2.同步的嵌套会产生死锁,过多的同步会产生死锁

public class  DeadLock 
{
	public static void main(String[] args) 
	{
		MyLock lock1=new MyLock();
		MyLock lock2=new MyLock();
		lock1.flag=true;
		lock2.flag=false;

		Thread t1=new Thread(lock1);
		Thread t2=new Thread(lock2);
		t1.start();
		t2.start();
	}
}



class ZhangSan
{
	public void say()
	{
		System.out.println("张三说你把画给我!");

	}

	public void get()
	{
		System.out.println("张三得到了画");
	}
}


class LiSi
{
	public void say()
	{
		System.out.println("李四说你把书给我!");

	}

	public void get()
	{
		System.out.println("李四得到了书");
	}
}


class MyLock implements Runnable
{
	boolean flag;
	private static ZhangSan zs=new ZhangSan();//声明static类型对象,数据共享
	private static LiSi ls=new LiSi();//static很重要
	

	public void run()
	{
		if(flag)
		{
		   zs.say();
		   synchronized(zs)
			{
				try{Thread.sleep(200);}catch(Exception e){}
				synchronized(ls)
				{
					zs.get();
				}
			}

		}else
		{
		   ls.say();
		   synchronized(ls)
			{
				try{Thread.sleep(200);}catch(Exception e){}
				synchronized(zs)
				{
					ls.get();
				}
			}
		}
	}
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics