黑马程序员——Java多线程

------- android培训java培训、期待与您交流! ----------

Java多线程

采用Java中的多线程机制可以使计算机资源得到更好的利用,可以使程序在同一时间内完成很多操作。
进程:正在计算机中执行的程序;
线程:线程是进程中某一个单一顺序的控制流。
多线程:程序可以同时运行多个程序块,程序运行效率得到提高。

创建多线程:
1、 通过继承Thread类创建:
class  类名称 extends Thread
{
	属性...
	方法...
	修饰符 run()
	{
		以线程处理的程序;
	}   
}





继承 Thread 类,覆盖方法 run()
我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可。
下面是一个例子:
public class MyThread extends Thread 
{
	int count= 1, number;
	public MyThread(int num)
	{
		number = num;
		System.out.println("创建线程 " + number);
	}
	public void run() 
	{
		while(true) 
		{
			System.out.println("线程 " + number + ":计数 " + count);
			if(++count== 6) return;
		}
	}
	public static void main(String args[]) 
	{
		for(int i = 0; i < 5; i++) new MyThread(i+1).start();
	}
}




  2、通过实现Runnable接口创建多线程:
class 类名 implements Runnable
{
	属性...
	方法...
	修饰符 run();
	{
		以线程处理的程序;
	}
}




下面是一个例子:
public class MyThread implements Runnable 
{
	int count= 1, number;
	public MyThread(int num)
	{
		number = num;
		System.out.println("创建线程 " + number);
	}
	public void run() 
	{
		while(true)
		{
			System.out.println("线程 " + number + ":计数 " + count);
			if(++count== 6) return;
		}
	}
	public static void main(String args[])
	{
		for(int i = 0; i < 5; i++) new Thread(new MyThread(i+1)).start();
	}
}


3、运行线程:

3.1、继承Thread类方式线程的启动:

ThreadDemo 线程对象 = new ThreaDemo();
线程对象.start();

3.2、实现Runnable接口线程的启动:

ThreadDemo 线程对象 =new ThreadDemo();
Thread 实例m=new Thread(线程对象);
实例m.start();

4、线程的调度:处于生命周期中的线程,可以通过调度实现各种状态间的转换。
 线程调度方法:设置优先级,睡眠,让步和等待等方法。

4.1、优先级:public final void setPriority(int i);//设置优先级(0-10)。

4.2、睡眠:public static void sleep(long millis) throws InterruptedException;//休眠时间参数为毫秒。
      public static void sleep(long millis, int nanos) throws InterruptedException;//休眠时间参数指定的毫秒数加纳秒数。
 sleep() 方法:sleep() 允许 指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间内进入阻塞状态,不能得到 CPU 时间,指定的时间一过,线程重新进入可执行状态。典型地,sleep() 被用在等待某个资源就绪的情形:测试发现条件不满足后,让线程阻塞一段时间后重新测试,直到条件满足为止。

4.3、让步:public static void yield();//静态方法,运行到时,线程回到就绪状态。

4.4、等待:public static void sleep(long millis) throws InterruptedException;//休眠时间参数为毫秒。
      public static void  sleep () throws InterruptedException;//指定的线程执行完毕再执行其他线程。
          public static void sleep(long millis,int nanos) throws InterruptedException  ;     //休眠时间参数指定的毫秒数加纳秒数。

5、多线程同步:
访问控制符 synchronized 返回值类型 方法名(参数);//使用关键字synchronized实现线程同步。
{
...;//方法体
}
 synchronized 方法: 通过在方法声明中加入 synchronized 关键字来声明 synchronized
方法。如:public synchronized void accessVal(int newVal);
1、synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
   在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。synchronized 方法的缺陷:若将一个大的方法声明为 synchronized 将会大大影响效率,
典型地,若将线程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是synchronized 块。

2、 synchronized 块:通过 synchronized 关键字来声明 synchronized 块。语法如下:
synchronized(syncObject) 
{
	//允许访问控制的代码
}

synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,
可以是类实例或类)的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任
意指定上锁的对象,故灵活性较高。



6、死锁:线程对象可能永远同步方法,这时候会出现一个线程等另一个对象,而另一个对象在等下一个对象,这样就会形成环状,即死锁。
      避免死锁:确保在获取多个锁时,在所有的线程中都以相同的顺序获取锁。

7、线程间通信:Java提供了wait(),notify(),notifyAll()方法来十年线程间通信机制。这些方法在根类Object中用关键字final声明。
 wait() 和 notify() 方法:两个方法配套使用, wait() 使得线程进入阻塞状态,它有两种形式,一种允许 指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify() 被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的notify() 被调用。初看起来它们与 suspend() 和 resume() 方法对没有什么分别,但是事实上它们是截然不同的。区别的核心在于,前面叙述的所有方法,阻塞时都不会释放占用的锁(如果占用了的话),而这一对方法则相反。


------- android培训java培训、期待与您交流! ----------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值