黑马程序员------多线程

android培训java培训

1,多线程:进程是一个正在执行的程序,线程是进程中的一个独立的控制单元,线程控制着进程的执行,一个进程中至少有一个线程。

2,如何创建线程:
  方法一:定义一个类继承Thread类,并覆写它的run()方法。

class ThreadDemo extends Thread{
		  public void run(){
				  //需要同步的代码。
		  }
		  public static void main(String[] args){
		  	//每new一个新的Thread的子类对象,就创建了一个线程,当调用这个对象的start()方法时启动一个线程
		    new ThreadDemo().start();
		    for(int i=0;i<100;i++)
		    	System.out.println("main is run");
		  }
		}


  方法二:自定义一个类实现Runnable接口,并覆写Runnable中的run方法,将此类的对象作为参数传入Thread的构造函数中,
          然后通过Thread对象的start方法开启线程。

class Ticket implement Runnable{
		  public void run(){
		    //需要多线程运行的代码;
		  }
		}
		class TicketDemo{
		  public static void main(String[] args){
		    new Thread(new Ticket()).start();
		    new Thread(new Ticket()).start();
		  }
		}


  注意:多个线程都在获取cpu的执行权,在某一时刻cpu只能执行一个程序(多核除外)。
3,线程的常用方法:currentThread(); //返回当前正在执行的线程引用。
           getName();    //返回该线程的名称。
           getPriority();  //返回该线程的优先级。
           interrupt();   //强制清除线程的中断状态,使其恢复到运行状态,抛出InterruptedException异常。
           isAlive();    //测试线程是否处于活动状态。
           join();     //等待该线程终止。当a线程执行到了b线程的join方法时,a线程要等b线程执行完后再继续执行。
           setName(String s); //设置线程名称。
           setDaemon(boolean on) //需要在线程开启之前设置,守护线程也叫后台线程,当所有前台线程都结束时后台线程自动结束。
           setPriority(int i);//设置线程的优先级。也可以自定义(1-10之间的数)。
          线程的三个优先级 :MAX_PRIORITY
                  MIN_PRIORITY
                  NORM_PRIORITY  
           sleep(long l);  //让线程休眠long秒。是线程的冻结状态。
           yield();     //暂停当前的线程对象,执行其他线程。
                wait()&notify;  //等待唤醒线程,是线程的冻结状态,cpu放弃了执行资格。
             stop();  //线程停止。还有一种情况就是run方法执行完成。
4,多线程运行时会出现安全问题,产生安全问题的原因:当多条语句操作同一个线程的共享数据时,一个线程只执行了多条语句的一部分,
   没有全部执行完,而另个一线程抢到了执行权,对共享数据进行操作,造成共享数据错误。
   解决办法:让一个线程把多条语句执行完,如果一个线程正在执行共享语句,没有执行完,其他线程不能操作共享语句。
   java中提供了同步代码块synchronized(锁){要被同步的代码}
   同步的前提:1,必须有两个以上的线程。
             2,多个线程必须使用的是同一个锁。
5,synchronized关键字。 
   同步函数:public synchronized void show(){}   //此函数用的同步锁是 this。
   静态同步函数:publlic static synchronized void show(){}  //此方法使用的同步锁是此静态函数所在的类的类名.class文件。

同步代码块的应用,单例设计模式。
	 懒汉式:class Single{
		          private static Single s = null;				//先不new对象,调用时在new对象。
		          private Single(){}
		          public static Single getInstance(){		
		            if(s==null){												//双重判断。
		              synichronized(Single.class){
		              	if(s==null){
		              	  s = new Single();
		              	  
		              	}
		              }
		            }
		            return s;
		          }
					 }

6,死锁:在多线程中,当一个同步代码中嵌套另一个同步代码,而且两段代码持有的锁不一样,而且互相需要对方的锁时会发生死锁。

例如:class LockDemo implements Runnable{
 				public static Object locka = new Object();
 				public static Object lockb = new Object();
 				private boolean flag = true;
 				
 				LockDmeo(boolean flag){
 					this.flag = flag;
 				} 
 				
 				public void run(){
		 				if(flag){
		 				  while(true){
		 				  	synchronized(locka){    //线程1进入拿到locka锁
		 				  		System.out.println("111");  //执行到此处,执行权被线程2抢走。
		 				  		synchronized(lockb){        //1线程抢回执行权,但是需要lockb锁,线程2没有释放lockb锁,所以形成死锁。
		 				  			System.out.println("222");
		 				  		}
		 				  	}
		 				  }
		 				}
		 				else{
		 					while(true){
		 						synchronized(lockb){   //线程2拿到lockb锁,需要locka锁,而线程1没有释放locka锁。
		 				  		System.out.println("333");
		 				  		synchronized(locka){
		 				  			System.out.println("444");
		 				  		}
		 				  	}
		 					}
		 				}
 				}
 				
 				public static void main(String[] args){
 				  new Thread(new LockDemo(true)).start();
 				  new Thread(new LockDemo(false)).start();
 				}
      }

7,Lock接口:1.5的新特性!可以支持多个相关的 Condition 对象。
  lock()、unlock()方法替代了原来的synchronized().
  通过lock.newCondition()获得一个Condition对象,Condition对象中的await()方法替换了wait()方法,signal()、signalAll()方法
  替换了原来的notify()、notifyAll()方法.
  可以通过创建多个Condition对象来指定要等待的对象和要唤醒的对象。
  通过Lock对多线程进行同步的一个实例:

 

package lockday1;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Resource {
	private String name;
	public int count = 1;
	private boolean flag = false;
	final Lock lock = new ReentrantLock();
	final Condition locka = lock.newCondition();
	final Condition lockb = lock.newCondition();
	
	public void set(String name){
		lock.lock();
		while(flag){
			try {
				locka.await();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.name = name + count;
		count++;
		System.out.println(Thread.currentThread().getName()+"生产者------------"+this.name);
		flag = true;
		lockb.signal();
		lock.unlock();
	}
	public void get(){
		lock.lock();
		while(!flag){
			try {
				lockb.await();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println(Thread.currentThread().getName()+"消费者----"+this.name);
		flag = false;
		locka.signal();
		lock.unlock();
	}
}

class Producer implements Runnable{
	private Resource r;
	
	Producer(Resource r){
		this.r = r;
	}
	public void run(){
		
			while(true)
				if(r.count<1000){
					r.set("汽车");
				}
		
	}
}
		
class Consumer implements Runnable{
	private Resource r;
	Consumer(Resource r){
		this.r = r;
	}
	public void run(){
		
			while(true)
				if(r.count<1000){
					r.get();
				}
	}
}

package lockday1;

public class LockTest1 {
		public static void main(String[] args){
			Resource r = new Resource();
			new Thread(new Producer(r)).start();
			new Thread(new Consumer(r)).start();
		}
}
	



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值