zoukankan      html  css  js  c++  java
  • 多线程(二)



    线程生命周期


    new               新建状态

    runnable     运行状态

    blocked       阻塞状态、等待某个监视器的锁

    waiting         冻结状态、无限等待某个监视器的锁

    timed-waiting   等待状态、由另一个线程决定等待的时间

    terminated     退出状态




    线程控制


    让run()结束,控制循环让run方法结束




    join()

    调用join方法的线程对象强制运行,该线程强制运行期间,其他线程无法运行.但是在调用join()方法之前开起的方法可以运行。

    import java.util.*;
    class ThreadTest implements Runnable
    {
    	public void run()
    	{
    		for(int i=0;i<100;i++)
    			System.out.println(Thread.currentThread().getName()+"running");
    	}
    }
    class ThreadDemo
    {
    	public static void main(String[] args) 
    	{
    		ThreadTest t=new ThreadTest();
    		Thread t1=new Thread(t,"b");
    		new Thread(t,"a").start();        //要先start(),因为join()不会调用run方法,它只是强制让该线程执行完才会执行下面的线程。但是在join之前的执行的线程照常执行。
    		t1.start();                   
    		try
    		{
    			t1.join();                      //会抛出InterruptedException
    		}
    		catch(InterruptedException e)
    		{
    			e.printStackTrace();
    		}
    		new Thread(t,"c").start();
    	}
    }


    多线程安全


    当多个线线程同时操作一个类的数据,其结果与单个线程操作的结果一样,说明是同步的、安全的。


    不安全的线程



    class ThreadTest implements Runnable
    {
    	private int tickts=100;
    	public void run()
    	{
    		for(;tickts>0;)
    		{
    			try
    			{
    				Thread.sleep(10);
    			}
    			catch(InterruptedException e)
    			{
    				e.printStackTrace();
    			}
    			
    			System.out.println(Thread.currentThread().getName()+" sale No."+tickts--);
    		}
    	}
    }
    class ThreadDemo
    {
    	public static void main(String[] args)
    	{
    		ThreadTest tt=new ThreadTest();
    		new Thread(tt,"A").start();
    		new Thread(tt,"B").start();
    		new Thread(tt,"C").start();
    	}
    }



    会出现一张票卖两次的情况。

    因为当C线程执行到sleep之后丧失了CPU执行权,这时A线程获得执行权将代码执行到了System。然后C又获得了执行权,此时tickts为0的值以被A线程先执行了。




    同步代码

    class ThreadTest implements Runnable
    {
    	private int tickts=100;
    	public void run()
    	{
    		                       
    			for(;tickts>0;)
    			{
    				synchronized(this)		                       //当一个线程执行到这时,就像关了门一样,只要先进去的线程不出来,后面的线程就不能执行该代码块中的内容
    				{			
    					try
    					{
    						Thread.sleep(10);
    					}
    					catch(InterruptedException e)
    					{
    						e.printStackTrace();
    					}
    			
    					System.out.println(Thread.currentThread().getName()+" sale No."+tickts--);
    				}
    			}
    		
    	}
    }
    class ThreadDemo
    {
    	public static void main(String[] args)
    	{
    		ThreadTest tt=new ThreadTest();
    		new Thread(tt,"A").start();
    		new Thread(tt,"B").start();
    		new Thread(tt,"C").start();
    	}
    }

    线程通信

    让A线程执行一段代码,紧接B线程执行一代码,轮回执行。

    import java.util.concurrent.locks.*;
    import java.util.*;
    class Person
    {
    	private String name;
    	private String sex;
    	ReentrantLock lock=new ReentrantLock();
    	Condition jin=lock.newCondition();
    	Condition chu=lock.newCondition(); 
    	private int flag=0;								//定义一个标记
    	public void set(String name,String sex)
    	{
    		lock.lock();   								//锁
    		try
    		{
    			if(flag==1)								//如果有值flag为1,为1就不胜存值了,等待输出
    			{
    				try
    				{
    					jin.await();                   //设置线程等待
    				}
    				catch(InterruptedException e)
    				{
    					e.printStackTrace();
    				}
    			}
    			this.name=name;
    			this.sex=sex;
    			System.out.println("Setting...........");
    			flag=1;                                  //存完值后将标记设为1
    			chu.signal();                            //唤醒输出线程
    		}
    		finally
    		{
    			lock.unlock();
    		}
    	}
    	public void get()
    	{
    		lock.lock();
    		try
    		{
    			if(flag==0)								//if flag is 0,the thread of printing wont print.waiting for setting.
    			{
    				try
    				{
    					chu.await();					//thread of print is waiting.
    				}
    				catch(InterruptedException e)
    				{
    					e.printStackTrace();
    				}
    			}
    			System.out.println(this.name+"....."+this.sex);
    			flag=0;										//输出后将标记设为0
    			jin.signal();								//唤醒设置线程
    		}
    		finally
    		{
    			lock.unlock();
    		}
    	}
    }
    class in implements Runnable
    {
    	private Person p;
    	in(Person p)
    	{
    		this.p=p;
    	}
    	public void run()
    	{
    		for(int i=0;i<100;i++)
    		{
    		if(i%2==0)
    			p.set("ZhangSan","man");
    		else
    			p.set("WangLi","woman");
    		}
    	}
    }
    class out implements Runnable
    {
    	private Person p;
    	out(Person p)
    	{
    		this.p=p;
    	}
    	public void run()
    	{
    		for(int i=0;i<100;i++)
    		{
    			p.get();
    		}
    	}
    }
    class ThreadDemo
    {
    	public static void main(String[] args)
    	{
    		Person p=new Person();
    		new Thread(new in(p)).start();
    		new Thread(new out(p)).start();
    	}
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    





  • 相关阅读:
    WINCE6.0新建工程编译出错的问题
    单片机C语言中的data,idata,xdata,pdata,code
    WinCE 6.0学习笔记一
    Visual Studio 2005 学习笔记一 入门
    Zigbee系列 学习笔记六(设置项)
    Zigbee系列 学习笔记五(信道选择)
    Zigbee系列 学习笔记四(睡眠及唤醒)
    Zigbee系列 学习笔记三(初始化程序解析)
    Zigbee调试问题 IAR编译出现 Fatal Error[e72]: Segment BANKED_CODE must be defined in a segment definition option (-Z, -b or -P)
    关于懒设计
  • 原文地址:https://www.cnblogs.com/lisisong/p/5122623.html
Copyright © 2011-2022 走看看