黑马程序员_java_多线程2

来源:互联网 发布:node js redis 编辑:程序博客网 时间:2024/06/08 19:54

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

同步函数:

show();方法本身没有同步性,但我们加上sychronized标记后就具备了同步性。

class Ticket implements Runnable  {      private int num = 100;      //private Object obj = new Object(); 同步函数使用的锁是this 这里我们将boject注释掉,程序也没问题,    public  void run()      {          while(true)          {              show();          }      }      //同步函数      public synchronized void show()      {          if(num>0)          {              try{Thread.sleep(10);}catch(InterruptedException e){}              System.out.println(Thread.currentThread().getName()+".....sale....."+num--);          }      }  }  class TicketDemo3   {      public static void main(String[] args)       {          Ticket t = new Ticket();                    //创建线程对象。                    Thread t1 = new Thread(t);          Thread t2 = new Thread(t);          Thread t3 = new Thread(t);          Thread t4 = new Thread(t);            t1.start();          t2.start();          t3.start();          t4.start();      }  }  
那么同步函数和同步代码块的区别是:①书写,同步函数书写简单②用的锁不一样,同步函数使用的锁是this;同步代码块使用的锁是任意对象

然而当静态方法在编译的时候还没有this也没有对象,所以静态方法若要同步,使用的锁是该类字节码文件对象----表示方式:类名.class

死锁

最常见的死锁情况,同步的嵌套:同步中还有同步,两个同步用的不是一个锁。

 我们应当,尽量避免同步嵌套的情况。

class Clock {  //锁使用的2个对象    public static Clock locka = new Clock();      public static Clock lockb = new Clock();  }  class DeadLock implements Runnable {      private boolean flag;  //定义Boolean变量    public DeadLock(boolean flag){          this.flag = flag;      }       @Override      public void run() {          if(flag){  //让2个线程进入不同的锁当中            while(true){                  synchronized(Clock.locka){  //线程T1在locka的锁准备进入lockb的锁中                    System.out.println(".................if locka");                      synchronized(Clock.lockb){                          System.out.println(".................if lockb");                      }                  }              }          }          else{              while(true){                  synchronized(Clock.lockb){  线程t2在lockb的锁中准备进入locka的锁中                    System.out.println("-------------------------else lockb");                      synchronized(Clock.locka){                          System.out.println("----------------------else locka");                      }                  }              }          }      }     }   public class DeadLockTest {        public static void main(String[] args) {          DeadLock d1 = new DeadLock(true);  //创建对象,并设定Boolean值        DeadLock d2 = new DeadLock(false);  <span style="font-family: Arial;">//创建对象,并设定Boolean值</span>               Thread t1 = new Thread(d1);  //创建线程,传人对象        Thread t2 = new Thread(d2);          t1.start();  //开启线程        t2.start();            }  }  
例中,当先线程当t1 拿到 Clock.locka , 当线程t2 拿到 Clock.lockb时,线程t1 需要 Clock.lockb 来继续运行,线程t2 需要 Clock.locka 来继续运行,而此时锁中都有运行着的线程,对方不能进入,造成了死锁的状况。

java中的等待唤醒机制

class Resource {      private String name ;      private String sex;      private boolean flag = false;          public synchronized void set(String name , String sex){                 if(flag)              try {                  wait();              } catch (InterruptedException e) {                  e.printStackTrace();              }                      this.name = name;  //设置成员变量              this.sex = sex;                        flag = true;   //设置之后,Resource中有值,将标记该为 true ,                         this.notify(); //唤醒output         }      public synchronized void out(){          if(!flag)              try {                  wait();              } catch (InterruptedException e) {                                 e.printStackTrace();              }                     System.out.println("The name is : " + name + " &&  The sex is : " + sex); //输出线程将数据输出               flag = false;//改变标记,以便输入线程输入数据                           this.notify(); //唤醒input,进行数据输入         }   }   class Input implements Runnable {       private Resource r;      public Input(Resource r){          this.r = r;      }      public void run() {          int count = 0 ;           while(true){              if(count == 0){                  r.set("Tom", "man");              }else{                  r.set("Lily", "woman");              }                        count = (count + 1)%2; //每执行到一次设置一次name和性别。            }      }  }   class Output implements Runnable {       private Resource r ;      public Output(Resource r ){          this.r = r;      }       public void run() {          while(true){              r.out();          }       }  }  public class ResorseDemo {       public static void main(String[] args) {                Resource r = new Resource(); //资源对象                  Input in = new Input(r); //任务对象            Output out = new Output(r);                Thread t1 = new Thread(in); //线程对象            Thread t2 = new Thread(out);                 t1.start();  //开启线程t1           t2.start();           }  }  

在这个例子中,我们应用了等待唤醒机制:input() 和output()利用wait()和notify();及设置Boolean值来交替输入和打印一组姓名----年龄。

线程的优先级

当有多个线程同时处于可执行状态(就绪状态)哄抢CPU控制权时
优先级能够使得优先级高的线程有更大的机会获得 CPU 控制权,优先级低的线程机会要小

JAVA 里面定义了10级

可以用setPriority来设置线程的优先级,getPriority取得线程的优先级:

import sharevar.Machine;public class priority extends Thread {    private static StringBuffer log=new StringBuffer();    private static int count=0;      public void run() {        for (int a=0;a<20;a++) {            log.append(currentThread().getName()+":"+a);            if (++count %10==0) log.append("\n");        }    }    public static void main(String[] args) {        // TODO Auto-generated method stub        Machine m1=new Machine();        Machine m2=new Machine();        m1.setName("m1");        m2.setName("m2");        Thread main=Thread.currentThread();   //获得主线程        //查看和设置线程的优先级        System.out.println("default priority of main:"+main.getPriority());        //打印m2线程默认优先级        System.out.println("default priority of m1:"+m1.getPriority());        //打印m2线程默认优先级        System.out.println("default priority of m2:"+m2.getPriority());            m2.setPriority(Thread.MAX_PRIORITY);        m1.setPriority(Thread.MIN_PRIORITY);        m1.start();//开启线程        m2.start();        System.out.println(log);    }}




0 0
原创粉丝点击