小白线程入门(二)

---恢复内容开始---


在这个代码中,我们在main方法中,写了一个for循环,在Tred类中创建了一个线程,并重写了它的run方法,在run方法中写了一个for循环,当我们运行此程序时结果如下:

主程序中的for循环,输出了五次之后,线程Tred启动,也执行了五次,这是线程正常运行的情况,没有发生数据的混乱




当应用中存在多个线程时,程序的执行流程将不再保证会按照原有单线程的执行流程,有可能会出现各个线程之间互相打断的情况。下面我们来看看多线程安全问题,我们经常提到的卖票问题:

package com.itycl.ch01;
public class ThreadDemo2 {
 public static void main(String[] args) {
  
  TicketWindow tw1 = new TicketWindow();
  TicketWindow tw2 = new TicketWindow();
  TicketWindow tw3 = new TicketWindow();
  
  tw1.start();
  tw2.start();
  tw3.start();
 }
}
class TicketWindow extends Thread{
 
 private  int ticket = 100;
 
 public void run(){
  
  while(true){
   if(ticket > 0){
    System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket-- +"张票");
   }
  }
  
 }
}

运行结果Thread-0正在出售第100张票

                  Thread-2正在出售第100张票

                  Thread-1正在出售第100张票

                  Thread-1正在出售第90张票

                  Thread-2正在出售第80张票

                  Thread-1正在出售第98张票

 在此程序中我们创建个三个线程,把他们当作卖票的窗口,共同去卖100张票,当我们看到,运行结果,Thread-0,Thread-1,Thread-2,都同时在卖第100张票,此时就出现了错票,这是为什么呢?我们发现我们的三个线程都能去卖同一张票。这时我们在private  int ticket = 100;加关键字static修饰变量时,将变量设置为共享数据,就能解决此问题了。

package com.itycl.ch01;
public class ThreadDemo2 {
 public static void main(String[] args) {
  
  TicketWindow tw1 = new TicketWindow();
  TicketWindow tw2 = new TicketWindow();
  TicketWindow tw3 = new TicketWindow();
  
  tw1.start();
  tw2.start();
  tw3.start();
 }
}
class TicketWindow extends Thread{
 
 private static int ticket = 100;
 
 public void run(){
  
  while(true){
   if(ticket > 0){
    System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket-- +"张票");
   }
  }
  
 }
}
 

当多条语句在操作同一个线程共享数据时,

一个线程对多条语句只执行了一部分(,CPU就切换到其他线程去了),还没执行完,

另一个线程就参与进来执行,导致共享数据的错误。

这时候引出来了 synchronized关键字,在run方法中加入了同步代码块,它相当于一把锁,当它持有资源的时候,别的线程不能进入来执行,只有它 运行完了,其他的线程才能运行
package com.itycl.ch01;
public class ThreadDemo2 {
 public static void main(String[] args) {
  
  TicketWindow tw1 = new TicketWindow();
  TicketWindow tw2 = new TicketWindow();
  TicketWindow tw3 = new TicketWindow();
  
  tw1.start();
  tw2.start();
  tw3.start();
 }
}
class TicketWindow extends Thread{
 
 private int ticket = 100;
 Object o=new Object();
 public void run(){
  
  while(true){
synchronized(o){
   if(ticket > 0){
    System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket-- +"张票");
}
   }
  }
  
 }
}

---恢复内容结束---

猜你喜欢

转载自www.cnblogs.com/Overmatch/p/9775549.html