黑马-----JAVA中多线程浅记

来源:互联网 发布:大数据推荐系统 视频 编辑:程序博客网 时间:2024/06/06 04:10

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

1.进程:是一个正在执行的程序。

2.线程:就是进程中的一个独立的控制单元

3.线程创建的两种方法:

 方法一:继承Thread类

(1)从Thread类派生出一个子类,在类中一定要实现run(),

class Lelfthand extends Thread{

           public void run(){

                         …

            }

 

}

(2)然后用该类创建一个对象:如:

Lefthand  left=new  Lefthand();

(3)用start()方法启动线程;如:

left.start();

方法二:实现Runnable接口

 

public class xyz implements Runnable{

            int i;

            public void run(){

                      while(true){

                                System.out,println("Hello"+i++);

                      }

             }

}

利用它可以构造一个线程如下:

Runnable r=new xyz();

Thread t=new Thread(r);

 

总之:线程由Thread 对象的实例来引用。线程执行的代码来源于传递给Thread构造方法的参数引用的类,

这个类必须实现了接口Runnable,线程操作的数据源于传递给Thread构造方法的Runnable实例。

 

 

 

4.多线程的运行出现的安全问题:

(1)问题的原因:

      当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分
还没有执行完,另一个线程参与进来执行,导致共享数据的错误
(2)解决办法:
 JAVA对于多线程的安全问题提供了专业的解决方式:
  同步代码块:

synchronized(对象) //锁或监视器


{

  需要被同步的代码;


}


注意:对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取cpu的执行权,

也进不去,因为没有获取锁


同步的前提:
     1.)必须要有两个或者两个以上的线程
     2.)必须是多个线程使用同一个锁,


好处:解决了多线程的安全问题
弊端:多个线程需要判断锁,较为消耗资源



如何找问题:

1.)明确哪些代码是多线程运行代码,
2.)明确共享数据,
3.)明确多线程运行代码中哪些语句是操作共享数据的

(5)死锁:同步中嵌套同步。

(6)线程间的通信:其实就是多个线程在操作同一个资源,但是操作的动作不同。
经典同步问题:

生产者--------消费者
class ProducerConsumerDemo
{
  public static void main(string[] args)
  {
    Resource r=new Resource();
    Producer pro=new Producer(r);
    Consumer con=new Consumer(r);
    Thread t1=new Thread(pro);
    Thread t2=new Thread(pro);
    Thread t3=new Thread(con);
    Thread t4=new Thread(con);
    t1.start();
    t2.start();
    t3.start();
    t4.start();
   }


}

class Resource
{
  private String name;
  private int count=1;
  private boolean flag=false;
  public void set(String name)
 {  
      if(flag)
       try{wait();}catch(Exception e){}
      this.name=name+"--"+count++;
      System.out.println(Thread.currentThread().getName()+"----生产者----"+this.name)
       flag=true;
       this.notifyAll();
  }
  public void out()
  {
       if(!flag)
       try{wait();}catch(Exception e){}
       System.out.println(Thread.currentThread.get.Name()+"----消费者----"+this.name)
       flag=false;
       this.notifyAll();

  }

}
class Producer implements Runnable
{
  private Resource res;
  Producer(Resource res)
  {
    this.res=res;


  }
public void run()
{
   while(true)
   {
   res.set("+商品+");

   }


}

 

}
class Consumer implements Runnable
{
     private Resource res;
  Producer(Resource res)
  {
    this.res=res;


  }
public void run()
{
   while(true)
   {
   res.out("+商品+");

   }

 


}


等待唤醒机制:
wait();等待
notify();/notifyAll();  唤醒

  

JDK1.5中提供了多线程升级解决方案:

一个锁对应多个Condition对象 ,将同步synchronized替换成实现Lock操作,
将Object中的Wait,Notify NotifyAll,替换了Condition对象 ,该对象可以Lock锁,进行获取,实现了本方只唤醒对方操作.

(7)停止线程:
1.)定义循环结束标记:
    开启多线程运行,线程运行代码一般都是循环,只要控制了循环就可以让RUN方法结束,也就是线程结束 。
2.)使用interrupt(中断)方法
    该方法是结束线程的冻结状态,使线程回到运行状态中来

特殊情况:

当线程处于了冻结状态 ,就不会读取到标记,那么线程就不会结束。

(8)守护线程:  守护线程是为其他线程提供服务的线程,它一般应该是一个独立的线程,它的RUN方法是一个无限循环。

public boolean isDaemon()确定一个线程是否是守护线程

public void setDaemon(boolean)设定一个线程为守护线程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

原创粉丝点击