`
uusoft
  • 浏览: 11063 次
  • 性别: 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();
				}
			}
		}
	}
}

分享到:
评论

相关推荐

    多线程学习札记

    【多线程学习札记】 在编程领域,多线程技术是提高程序效率和响应能力的重要手段。本文主要探讨了C#中关于多线程的相关概念、实现方式以及线程管理,包括委托、事件和线程同步锁。 一、委托(Delegate) 委托在C#...

    labview论坛-LabVIEW 学习札记 - 第二卷

    7. **并行处理与多线程**:LabVIEW支持并行编程,利用并行计算提高程序执行效率。这部分可能涵盖如何创建并行任务,实现多线程编程。 8. **错误处理与调试**:有效的错误处理是任何程序的重要组成部分。学习札记...

    LabVIEW程序设计札记例程

    8. **并行编程**:LabVIEW支持多线程和并行编程,这对于优化性能和实时系统特别有用。理解并行执行的概念,可以提升你的程序效率。 9. **控件和函数库**:LabVIEW拥有庞大的内置函数库,涵盖了各种功能。通过例程,...

    LabView学习札记

    在“三(上)”和“三(下)”中,可能会讲解如何实现复杂的控制逻辑,如多线程编程,以及如何利用LabVIEW的分布式系统架构进行网络通信。此外,也可能涉及到如何将LabView与其他编程语言(如C++或Python)集成,以...

    LabVIEW学习札记

    8. **并行处理**: LabVIEW支持多线程和并行计算,特别是在多核处理器上,可以有效提升计算效率。 9. **文件I/O**: LabVIEW提供了强大的文件读写功能,能够处理各种数据格式,如CSV、TXT、Excel、XML等,便于数据...

    labview学习札记

    6. **并行编程**:LabVIEW支持多线程和并行计算,尤其在多核处理器环境下,可以充分利用硬件资源,提高程序运行效率。 7. **图形化用户界面**:前面板的设计是LabVIEW的一大特色,可以创建直观、交互性强的用户界面...

    JVM学习札记

    1. **线程安全**:确保多线程环境下对共享资源的正确访问。 2. **偏向锁**:一种轻量级锁机制,适用于对象只有一个线程访问的情况。 3. **轻量级锁**:比偏向锁稍微重一些,但仍属于非阻塞锁,适合少量线程竞争的...

    NI LabVIEW学习札记.zip

    9. **并行处理**:LabVIEW支持多线程和并行编程,可以有效利用多核处理器资源,提高计算效率。 10. **LabVIEW Real-Time与FPGA**:LabVIEW还提供了实时系统模块和FPGA模块,能够进行实时操作系统和现场可编程门阵列...

    学习PMD软件中的札记

    每种方式都有其优缺点,例如懒汉式在多线程环境下可能不安全,而饿汉式则会立即初始化单例,可能造成不必要的内存占用。因此,选择合适的单例实现方式需要考虑具体项目的需求和环境。 在实际应用中,我们还需要注意...

    C语言书籍和个人学习札记

    4. **并发编程**:涉及线程、信号、互斥锁、条件变量等,了解如何在C语言中实现多线程。 5. **异常处理**:虽然C语言没有内置的异常处理机制,但可以通过setjmp/longjmp等函数模拟。 6. **性能优化**:理解CPU缓存...

    觅职渣记-互联网技术类笔试面试总结

    - **多线程**:共享相同的地址空间,线程间通信简单快捷,但需要注意数据一致性问题。 **6. 死锁** 死锁是指两个或多个进程在执行过程中,由于竞争资源而造成的一种僵局状态。预防死锁的方法通常包括避免循环等待...

    401java-reading-notes

    这些笔记旨在帮助学员系统地掌握Java的知识体系,包括但不限于面向对象编程、数据结构、异常处理、多线程、网络编程、并发编程、数据库操作等内容。这个主题聚焦于Java的核心技术,适合初级到中级Java开发者或对Java...

    LabVIEW.rar_LabView编程_LabView_

    5. **并行处理**:由于LabVIEW的数据流模型,它可以方便地实现多线程和并行计算,提高程序执行效率。 6. **测试测量**:在测试测量领域,LabVIEW常用于搭建测试系统,例如自动测试设备(ATE)、信号分析、参数测量...

    Clojure Handbook(2012.11.1)

    这些数据结构都设计为不可变的,保证了程序的线程安全。 函数是Clojure中的基本构造单位。Handbook强调了函数在编程中的重要性,并讨论了函数的定义、柯里化、递归等概念。Clojure的函数可以作为一等公民,即函数...

Global site tag (gtag.js) - Google Analytics