发表于: 2017-12-29 19:45:09

2 502


今天完成的事:

       看了看多线程

明天计划的事:

        随便看看

问题:

收获:

多线程(守护线程)

* setDaemon(), 设置一个线程为守护线程, 该线程不会单独执行, 当其他非守护线程都执行结束后, 自动退出


多线程(加入线程)

* join(), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续

* join(int), 可以等待指定的毫秒之后继续

/**
* @param args
* join(), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续
*/
public static void main(String[] args) {
   final Thread t1 = new Thread() {
   public void run() {
   for(int i = 0; i < 10; i++) {
       System.out.println(getName() + "...aaaaaaaaaaaaa");
        }
    }
};
 
  Thread t2 = new Thread() {
public void run() {
  for(int i = 0; i < 10; i++) {
     if(i == 2) {
          try {
        //t1.join();
        t1.join(1);                //插队指定的时间,过了指定时间后,两条线程交替执行
              } catch (InterruptedException e) {

                e.printStackTrace();
              }
          }
          System.out.println(getName() + "...bb");
        }
}
};
 
  t1.start();
  t2.start();

多线程(礼让线程)

* yield让出cpu

###24.15_多线程(设置线程的优先级)

* setPriority()设置线程的优先级

###24.16_多线程(同步代码块)

* 1.什么情况下需要同步

* 当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步.

* 如果两段代码是同步的, 那么同一时间只能执行一段, 在一段代码没执行结束之前, 不会执行另外一段代码.

* 2.同步代码块

* 使用synchronized关键字加上一个锁对象来定义一段代码, 这就叫同步代码块

* 多个同步代码块如果使用相同的锁对象, 那么他们就是同步的

/**
   * @param args
   * 同步代码块
   */
  public static void main(String[] args) {
final Printer2 p = new Printer2();
     
     new Thread() {
public void run() {
while(true) {
p.print1();
           }
}
}.start();
     
     new Thread() {
public void run() {
while(true) {
p.print2();
           }
}
}.start();
  }

}

class Printer2 {
Demo d = new Demo();
  //非静态的同步方法的锁对象是神马?
  //答:非静态的同步方法的锁对象是this
  //静态的同步方法的锁对象是什么?
  //是该类的字节码对象
  public static synchronized void print1() { //同步方法只需要在方法上加synchronized关键字即可
     System.out.print("1");
     System.out.print("2");
     System.out.print("3");
     System.out.print("4");
     System.out.print("5");
     System.out.print("\r\n");
  }

public static void print2() {
//synchronized(new Demo()) {                     //锁对象不能用匿名对象,因为匿名对象不是同一个对象
     synchronized(Printer2.class) {
        System.out.print("6");
        System.out.print("7");
        System.out.print("8");
        System.out.print("9");
        System.out.print("\r\n");
     }
}
}

多线程(线程安全问题)(掌握)

* 多线程并发操作同一数据时, 就有可能出现线程安全问题

* 使用同步技术可以解决这种问题, 把操作数据的代码进行同步, 不要多个线程一起操作

/**
   * 需求:铁路售票,一共100张,通过四个窗口卖完.
   */
  public static void main(String[] args) {
new Ticket().start();
     new Ticket().start();
     new Ticket().start();
     new Ticket().start();
  }

}

class Ticket extends Thread {
    private static int ticket = 100;
  //private static Object obj = new Object();       //如果用引用数据类型成员变量当作锁对象,必须是静态的
  public void run() {
     while(true) {
       synchronized(Ticket.class) {
          if(ticket <= 0) {
              break;
           }try {
           Thread.sleep(10);           //线程1睡,线程2睡,线程3睡,线程4睡
           } catch (InterruptedException e) {

           e.printStackTrace();
           }
         System.out.println(getName() + "...这是第" + ticket-- + "号票");
        }
}
}
}

多线程(死锁)(了解)

* 多线程同步的时候, 如果同步代码嵌套, 使用相同锁, 就有可能出现死锁

* 尽量不要嵌套使用

private static String s1 = "筷子左";
  private static String s2 = "筷子右";

  public static void main(String[] args) {
new Thread() {
public void run() {
  while(true) {
    synchronized(s1) {
      System.out.println(getName() + "...获取" + s1 + "等待" + s2);
                 synchronized(s2) {
      System.out.println(getName() + "...拿到" + s2 + "开吃");
                 }
      }
   }
 }
}.start();
     
     new Thread() {
       public void run() {
         while(true) {
            synchronized(s2) {
                System.out.println(getName() + "...获取" + s2 + "等待" + s1);
                 synchronized(s1) {
                System.out.println(getName() + "...拿到" + s1 + "开吃");
                 }
      }
   }
 }
}.start();
  }
}



返回列表 返回列表
评论

    分享到