Java学习笔记(三):线程

1、线程的方法:

       (1)后台线程:调用setDaemon(true)设置,要在start()之前调用

package thirdDay;
class childDaemon implements Runnable
{
	public void run()
	{
		while(true)
		{
			System.out.println("thread is running");			
		}		
	}
}
public class setDaemon
{
	public static void main(String args[])
	{
		childDaemon c=new childDaemon();//定义一个类
		Thread cc=new Thread(c);//定义一个线程,将类赋给这个线程
		cc.setDaemon(true);//设置为后台线程
		cc.start();//线程启动
		//程序的运行结果:在主线程结束之前就退出了,只运行了几行循环;
		//说明它是后台线程;
	}
}
          (2)线程的强制执行:join

                      通过join就可以在一个线程里强制执行这个线程;

class joinThread1 implements Runnable
{
	public void run()
	{
		for(int i=0;i<1;i++)
			System.out.println(Thread.currentThread().getName()+"-->>"+i);
	}
}
public class joinThread {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread t=new Thread(new joinThread1());
		t.start();//此时启动线程,但是不知道什么时候执行
		for(int i=0;i<5;i++)
		{
			if(i==2)
				try
			{
				t.join();//强制执行,在第2次的时候
			}
			catch(Exception e)
			{
				e.getMessage();
			}
			System.out.println("Main is running");
		}
	}
}
/*下面是运行结果:
Main is running
Main is running
Thread-0-->>0
Main is running
Main is running
Main is running
*/
           (3)线程的休眠:sleep                

                           a、休眠线程可以被另一个线程终止,然后抛出异常;

                            b、休眠是静态方法,用Thread.sleep(200)调用;那么如何判断是哪个线程休眠:很简单,在哪个线程调用,就是哪个线程休眠;

package thirdDay;
class threadSleep extends Thread
{
	public void run()
	{
		loop();
	}
	public void loop()
	{
		String name=Thread.currentThread().getName();
		System.out.println(name+"---->>刚进入loop方法");
		for(int i=0;i<5;i++)
		{
			try
			{
				Thread.sleep(500);
			}
			catch(InterruptedException x)
			{}
			System.out.println("name="+name);
		}
		System.out.println(name+"---->>离开loop方法");
	}
}
public class sleepThread {
	public static void main(String[] args) {
		threadSleep tt=new threadSleep();		
		tt.setName("my worker thread");
		tt.start();//start就是启动一个新线程,然后调用run,调用loop
		try
		{
			Thread.sleep(500);//主线程等待,使得tt线程可以执行一部分;
		}					
		catch(InterruptedException x)//线程如果被中断,就会抛出异常;
		{}
		tt.loop();//主线程调用了loop方法,虽然主体是tt线程,但是却是主线程main在执行loop;
	}
}
/*下面是运行结果
my worker thread---->>刚进入loop方法
name=my worker thread
main---->>刚进入loop方法
name=main
name=my worker thread
name=main
name=my worker thread
name=main
name=my worker thread
name=my worker thread
name=main
my worker thread---->>离开loop方法
name=main
main---->>离开loop方法
*/
               (4)线程的中断:interrupted

                        

package thirdDay;

public class interruptedThread {
	public static void main(String[] args) {
		Thread t=Thread.currentThread();//此时t为主线程main
		System.out.println("A:t.isInterrupted="+t.isInterrupted());//输出true
		t.interrupt();//main线程被中断
		System.out.println("B:t.isInterrupted="+t.isInterrupted());//输出false
		System.out.println("C:t.isInterrupted="+t.isInterrupted());//输出false
		try//进入不了try,因为线程被中断
		{
			Thread.sleep(500);
			System.out.println("线程没有被中断");
		}
		catch(InterruptedException x)//main被中断,抛出异常,执行下面的代码
		{
			System.out.println("线程被中断");
		}	
		//因为sleep已经抛出了异常,所以它清除了中断标志
		System.out.println("D:t.isInterrupted="+t.isInterrupted());//输出true
	}
}
/*下面是输出结果:
	A:t.isInterrupted=false
	B:t.isInterrupted=true
	C:t.isInterrupted=true
	线程被中断
	D:t.isInterrupted=false
 */
	
2、线程的同步:

    (1)同步代码块:

                   在前面的卖票程序中,有可能同一张票打印两次或多次,也有可能打印的为0;

                  解决办法:

class TestThread implements Runnable
{
	private int tickets=20;
	public void run()
	{
		while(true)
		{
			synchronized(this)
			{
				if(tickets>0)
				{
					try
					{
						Thread.sleep(200);//加一个sleep,以让出cpu给其他的线程;
          //不然这个同步代码会一直循环执行,别的线程还没创建这个线程就已经执行完了
					}
			catch(Exception e){}				
			System.out.println(Thread.currentThread().getName()+"出售票"+tickets--);
				}
			}
		}
	}
}
public class synchronize {
	public static void main(String[] args) {
		TestThread t=new TestThread();
		new Thread(t).start();
		new Thread(t).start();
		new Thread(t).start();
		new Thread(t).start();
	}

}

         (2)同步方法:

                       跟代码块一样,就是把代码块封装到函数中;

package thirdDay;
class TestThread1 implements Runnable
{
	private int tickets=20;
	public void run()
	{
	
		while(true){
			sale();//这个while写在run里面,不能写在synchronized方法中
		}		//否则会一直在while里面,跳不出去,因为synchronized方法
				//只有里面的线程执行完后才会跳出来
	}
	public synchronized void sale()
	{			
			if(tickets>0)
			{
				try
				{
					Thread.sleep(300);
				}
				catch(Exception e){}				
				System.out.println(Thread.currentThread().getName()+"出售票"+
												tickets--);
			}		
	}
}
public class synchronize2 {
	public static void main(String[] args) {
		TestThread1 t=new TestThread1();
		new Thread(t).start();
		new Thread(t).start();
		new Thread(t).start();
		new Thread(t).start();
	}

}

3、关于线程的消费者和生产者模式:

              
package thirdDay;
import java.util.LinkedList;
/*
 *仓库类storage实现缓冲区
 */
class storage
{
	//定义一个最大存货量
	private final int MaxSize=100;
	//定义一个存货载体,就是一个变量代表存了多少货
	private LinkedList<Object> list=new LinkedList<Object>();
	//生产的num个数
	public void produe(int num)
	{
		//同步代码段
		synchronized(list)
		{
			//如果仓库的容量不足:list.size()仓库内目前有多少存货
			while(list.size()+num>MaxSize)
			{
				System.out.println("要生产的产品数量:"+num+"/t目前存货量:"+
								list.size()+"/t暂时不能执行生产任务!");
				try
				{
					//由于仓库的容量不足,所以阻塞生产
					list.wait();
				}
				catch(InterruptedException e)
				{
					e.printStackTrace();
				}							
			}
			//如果生产条件满足,就生产num个产品
			for(int i=1;i<=num;i++)
			{
				list.add(new Object());
			}
			System.out.println("已经生产的产品数量:"+num+"/t目前存货量"+
							list.size());
			//给其他等待的线程发出通知,同时自己放弃锁,处于等待状态;
			list.notifyAll();
		}
	}
	//消费num个产品
	public void consum(int num)
	{
		//同步代码段
		synchronized(list)
		{
			//如果要消费的大于库存量
			while(list.size()<num)
			{
				System.out.println("要消费的产品数量:"+num+"/t库存量:"+
								list.size()+"/t暂时不能执行生产任务");
				try
				{
					//由于条件不满足,消费阻塞
					list.wait();
				}
				catch(InterruptedException e)
				{
					e.printStackTrace();
				}							
			}
			//条件满足,消费num个产品
			for(int i=1;i<=num;i++)
			{
				list.remove();
			}
			System.out.println("已经消费产品数:"+num+"/t剩余库存数:"+list.size());
			list.notifyAll();
		}		
	}
	//get和set方法
	public LinkedList<Object> getList()
	{
		return list;
	}
	public void setList(LinkedList<Object> list)
	{
		this.list=list;
	}
	public int getMaxSize()
	{
		return MaxSize;
	}
}
//生产者类Producer继承Thread
class Producer extends Thread
{
	//生产数量
	private int num;
	//产品所要放置的仓库
	private storage storage;
	//构造函数,设置仓库
	public Producer(storage storage)
	{
		this.storage=storage;
	}
	//线程run函数
	public void run()
	{
		produce(num);
	}
	//调用仓库的生产函数
	public void produce(int num)
	{
		storage.produe(num);
	}
	//get和set方法
	public int getNum()
	{
		return num;
	}
	public void setNum(int num)
	{
		this.num=num;
	}
	public storage getStorage()
	{
		return storage;
	}
	public void setStorage(storage storage)
	{
		this.storage=storage;
	}		
}
//消费者类Consumer继承自Thread
class Consumer extends Thread
{
	//消费数量
	private int num;
	//产品所要放置的仓库
	private storage storage;
	//构造函数,设置仓库
	public Consumer(storage storage)
	{
		this.storage=storage;
	}
	//线程run函数
	public void run()
	{
		consum(num);
	}
	//调用仓库的消费函数
	public void consum(int num)
	{
		storage.consum(num);
	}
	//get和set方法
	public int getNum()
	{
		return num;
	}
	public void setNum(int num)
	{
		this.num=num;
	}
	public storage getStorage()
	{
		return storage;
	}
	public void setStorage(storage storage)
	{
		this.storage=storage;
	}	
}
//测试类主程序
public class produceAndConsum {
	public static void main(String[] args) {
		//仓库对象
		storage storage=new storage();
		//生产者对象
		Producer p1=new Producer(storage);
		Producer p2=new Producer(storage);
		Producer p3=new Producer(storage);
		Producer p4=new Producer(storage);
		Producer p5=new Producer(storage);
		Producer p6=new Producer(storage);

		//消费者对象
		Consumer c1=new Consumer(storage);
		Consumer c2=new Consumer(storage);
		Consumer c3=new Consumer(storage);

		//设置生产的产品的数量
		p1.setNum(10);
		p2.setNum(20);
		p3.setNum(30);
		p4.setNum(10);
		p5.setNum(20);
		p6.setNum(30);
		//设置消费的产品的数量
		c1.setNum(10);
		c2.setNum(20);
		c3.setNum(30);
		//线程开始执行
		c1.start();	c2.start();
		c3.start();
		p1.start();
		p2.start();
		p3.start();
	
	
	}
}




你可能感兴趣的:(Java学习笔记(三):线程)