java中的线程

如何创建一个控制单元或线程?
第一种方式:
1、继承Thread类。覆盖run方法,将多线程要运行的代码放到run方法中。
2、调用start方法,开启线程,并执行run方法。

   ※特性:随机性(每次执行的结果不一样,多个线程抢资源的结果)
   ※创建一个Thread类或其子类,才能够产生一个控制单元.

第二种方式:
1、实现Runnable接口,覆盖run方法.
2、调用Thread类建立线程对象,并将实现Runnable接口的子类对象作为参数传递给Thread的构造函数.
3、调用Thread类对象的start方法,开启并运行run方法.

为什么要将Runnable接口的子类对象作为参数传递给Thread类的构造方法呢?为了让多线程去执行自定义的run方法,该
run方法有自己所属的对象,所以将该对象传入.


 线程的安全问题,产生的原因:
 1、多个线程访问出现延迟;
 2、线程的随机性;
 同步:
 1、解决线程的安全问题,同时会消耗资源,降低效率(每个线程都需要去判断同步上的锁). 例子:火车上的卫生间(锁);
 2、需要同步的两个前提:①至少两个以上的线程;②多线程使用的是同一把锁;
 3、注意同步的死锁,尽量避免同步嵌套的情况.
 4、同步的两种表现形式:
 ①同步代码块,传递一个对象作为锁.
 ②同步函数,使用this作为锁。使用同步函数时,一定要注意分析哪些需要同步,在Tickets中,如将synchronized放到run方法上,
 那么线程进入while无限循环,无法退出,锁无法被其他线程使用.所以,while循环不需要同步,而其中的内容才是需要同步的内容.
 
 注意:1、线程在同步时,还是出现了安全隐患,结果很大程序出现在线程同步问题上,检查是否多线程使用的同一把锁.
    2、静态方法的同步函数,锁肯定不是this,因为静态方法不能使用this,这是,锁为方法所在的类的class对象,例如,Tickets.class.

class MyThread extends Thread
{
 private String name;
 MyThread(String name)
 {
  this.name = name;
 }
 public void run() //覆盖run方法
 {
  for (int x = 0; x < 10 ; x++)
  {
   System.out.println(Thread.currentThread().getName() + "..name:" + name + "-" + x);
  }
 }
}

//铁路售票例子,四个窗口同时售票
class Tickets implements Runnable
{
 private static int ticketsCnt = 100; //总共100张票 
 Object obj = new Object();
 boolean b = true;
 public void run()
 {
  //for (int x = ticketsCnt; x > 0; x--)  //为什么for循环这样写不行呢?
  if (b)
   
   while (true)
      
    show();   
   }
  }
  else
  {
   while (true)
   {
    synchronized(Tickets.class) //(this) //obj
    {
     if (ticketsCnt > 0)
     {
      try
      {
       Thread.sleep(10); //模拟线程的安全问题。
      }
      catch (Exception e)
      {
      //
      }
      System.out.println(Thread.currentThread().getName() + " ->code.... " +ticketsCnt--);   
     }
    }
     
  }
 }

 public synchronized static void show()  //同步函数,添加关键字synchronized,锁为this,如果声明为static,则锁为Tickets.class
 {
  if (ticketsCnt > 0)
  {
   try
   {
    Thread.sleep(10); //模拟线程的安全问题。
   }
   catch (Exception e)
   {
    //
   }
   System.out.println(Thread.currentThread().getName() + " ->func.... " +ticketsCnt--);   
  }
 }
}

class ThreadDemo
{
 public static void main(String[] args) // 当前程序有三个线程,包括主线程!
 {
  
  //MyThread d1 = new MyThread("one");  //线程1
  //MyThread d2 = new MyThread("two -");//线程2
  //d1.start();
  //d2.start();
  
  //主线程
  //for (int n = 0; n < 10; n++)
  //{
  // System.out.println(Thread.currentThread().getName() + ".." + n);
  //}
  

  Tickets t = new Tickets();
  Thread t1 = new Thread(t);
  Thread t2 = new Thread(t);
  //Thread t3 = new Thread(t);
  //Thread t4 = new Thread(t);
  
  t1.start();
  try
  {
   Thread.sleep(10); //让主线程停下来,不让程序首先执行 t.b = false;
  }
  catch (Exception e)
  {
   //
  }
  t.b = false;

  t2.start();
  //t3.start();
  //t4.start();
  
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值