线程2

>>3内部class类继承Thread的线程实现方式
public class TestThread
{
public static void main(String[] args)
{
  //实现Runnable接口得线程实现方式 用与和内部类比较
  MyThread myt1 = new MyThread();
  //new Thread(myt).start()的理解:根据myt对象,实例化一个线程对象,并开始线程
  new Thread(myt1).start();
//内部类继承Thread类的线程实现方式
  MyThread2 myt = new MyThread2();
  //由于内部类继承Thread类,所以可以使用start方法,但是方式很特别
  myt.new InnerThread().getThread().start();
  System.out.println("main方法线程名字:"+Thread.currentThread().getName());
}
}
//实现Runnable接口的 实现线程的方法
class MyThread implements Runnable
{
public void run()
{
  System.out.println("实现Runnable接口子线程得名字:"+Thread.currentThread().getName());
}
}
//内部类继承Thread类  实现线程 赞成频繁使用
class MyThread2
{
//定义内部类:1内部类继承Thread类或实现Runnable接口,覆盖run方法  2提供一个返回值是Thread的方法,返回内部类的对象 class InnerThread extends Thread
{
  public void run()
  {
    System.out.println("内部类输出线程名称:"+Thread.currentThread().getName());
  }
}
//返回值为线程类型的方法 实例化并返回内部类 (内部类实现线程的关键)Thread getThread()
public Thread getThread
{
  return new InnerThread();
}
}
>>4线程同步(synchronized)得实现:同步块和同步方法
public class TestThread
{
public static void main(String[] args)
{
  //四个线程同时销售100张票
  //同步块实现售票
  //SellThread myt = new SellThread();
  //new Thread(myt).start();//开启第一个窗口开始售票 即开启一个线程对同步对象惊醒操作 实现了共享数据同步操作
  //new Thread(myt).start();//开启第二个窗口开始售票 即开启一个线程对同步对象惊醒操作
  //new Thread(myt).start();//开启第三个窗口开始售票 即开启一个线程对同步对象惊醒操作
  //new Thread(myt).start();//开启第四个窗口开始售票 即开启一个线程对同步对象惊醒操作

//同步方法实现售票
  SellThread1 myt1 = new SellThread1();
  new Thread(myt1).start();//开启第一个窗口开始售票
  new Thread(myt1).start();//开启第二个窗口开始售票
  new Thread(myt1).start();//开启第三个窗口开始售票
  new Thread(myt1).start();//开启第四个窗口开始售票

}
}
//同步块 对某一个对象Ojbect进行加锁
class SellThread implements Runnable
{
int tickets= 100;//100张票
Object obj =  new Object();//同步变量
public void run()
{
  while(true)
  {
//给obj对象加锁,直到同步块结束,“{”表示给obj对象加锁,"}"表示给obj对象解锁
   synchronized(obj)  
{
    if(tickets>0)
    {
//sleep是Thread类的静态方法,调用时会抛出异常,需要捕获
     try{
      Thread.sleep(10);
     }catch(Exception e)
     {
      e.printStackTrace();
     }
     System.out.println("线程:"+Thread.currentThread().getName()+"sell==="+tickets);
     tickets--;
    }
   }
/*错误的方法:先锁住对象,在while循环,最终只走一个线程(与上边对比:先while再synchronized)
//同步块
synchronized(this)
{
while(tickets>0)    
   {
    try{
     Thread.sleep(1000);
    }
    catch(Exception e)
    {
     e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"sells tickets==="+tickets);
    tickets--;
   }
  }
*/
  }
}
}

//同步方法 对this加锁
class  SellThread1 implements Runnable
{
int tickets= 100;//100张票
//run方法调用同步方法sell
public void run()
{
  sell();
}
//声明同步方法的关键字:synchronized
public synchronized void sell()
{
  while(true)
  {
    if(tickets>0)
    {
     try{
      Thread.sleep(10);
     }catch(Exception e)
     {
      e.printStackTrace();
     }
     System.out.println("线程:"+Thread.currentThread().getName()+"sell==="+tickets);
     tickets--;
    }
  }
}
}

>>5 同步块和同步方法实现共享数据的同步
public class TestThread
{
public static void main(String[] args)
{  
//同步块和同步方法实现共享数据的同步(特点:同步块的同步对象为this,如果同步对象是obj,则会出现index=0)
  SellThread myt1 = new SellThread();  
  new Thread(myt1).start();//开启第一个窗口开始售票 启动第一个线程
  try{
   Thread.sleep(1);//主线程休眠
  }
  catch(Exception e)
  {
   e.printStackTrace();//sleep方法会抛出异常,所以需要捕获
  }
  myt1.bFlag = true;//改变bFlag得值为true
  new Thread(myt1).start();//开启第二个窗口开始售票

}
}
//对某一个Object对象进行加锁
class SellThread implements Runnable
{
int tickets= 100;//100张票
Object obj =  new Object();//同步变量
boolean bFlag = false;//同步方法和同步块转换的条件
public void run()
{  
   if(bFlag==false)
   {
    while(true)
     sell();
   }else    {
    while(true)
    {
     //同步块
synchronized(this)
     {
      if(tickets>0)
      {
       try{
         Thread.sleep(10);
        }
        catch(Exception e){
         e.printStackTrace();
        }
       System.out.println("同步块线程:"+Thread.currentThread().getName()+"sell==="+tickets);
       tickets--;
      }
     }
    }
   }
  
}

//同步方法
public synchronized void sell()
{
  if(tickets>0)
  {
   try{
    Thread.sleep(10);
   }
   catch(Exception e){
    e.printStackTrace();
   }
   System.out.println("同步方法线程:"+Thread.currentThread().getName()+"sell==="+tickets);
   tickets--;
  }
}
}


>>6线程同步时发生的死锁
线程A和B,A的同步对象m,n,B的同步也是对象m,n,进程A运行时先锁住m,进程B运行时先锁住n,A进程要用到n对象能完成但是n已经被B锁住,所以进程A进入等待状态,B进程要用到m对象才能完成但是m对象已经被A锁住,所以进程B也进入等待状态,出现死锁。
《红色标记为出现死锁得代码,注意与上例的比较》
public class TestThread
{
public static void main(String[] args)
{  
  SellThread myt1 = new SellThread();  
  new Thread(myt1).start();//开启第一个窗口开始售票
  try{
   Thread.sleep(1);//主线程休眠
  }
  catch(Exception e)
  {
   e.printStackTrace();//sleep方法会抛出异常,所以需要捕获
  }
  myt1.bFlag = true;//改变b得值为true
  new Thread(myt1).start();//开启第二个窗口开始售票
}
}
//对某一个对象进行加锁
class SellThread implements Runnable
{
int tickets= 100;//100张票
Object obj =  new Object();//同步变量
boolean bFlag = false;
public void run()
{
  
   if(bFlag==false)
   {
    while(true)
     sell();
   }else
   {
    while(true)
    {
    //同步块
synchronized(obj)
      {      
           try{
                     Thread.sleep(10);
            }
              catch(Exception e){
                    e.printStackTrace();
             }

                synchronized(this)
                 {
                      if(tickets>0)
                      {
                             System.out.println("同步块线程:"+Thread.currentThread().getName()+"sell==="+tickets);
                              tickets--;
                     }
            }
     }
    }
   }
  
}

//同步方法
public synchronized void sell()
{
  synchronized(obj)
  {
   if(tickets>0)
   {
    try{
     Thread.sleep(10);
    }
    catch(Exception e){
     e.printStackTrace();
    }
    System.out.println("同步方法线程:"+Thread.currentThread().getName()+"sell==="+tickets);
    tickets--;
   }
  }
  
}
}

>>7"生产者--消费者"模型 " 等待--通知(wait---notify)"模型。 一定是同步方法且作用同一个对象
public class TestThread
{
public static void main(String[] args)
{  
MyQueue q = new MyQueue();
//创建生产者
  Producer p = new Producer(q);
//创建消费者
  Consumer c = new Consumer(q);
//开始成产
  p.start();
//k开始消费
  c.start();
}
}
//树洞类 存放和取走数据
//存放和取走得方法都是同步的方法,且针对同一个变量value
class MyQueue
{
//数据变量value
int value =0;
//标记数据是否被取走得变量bFull
boolean bFull = false;
//消费者获得数据得方法
synchronized int  get()
{
  //如果不是满的,也就是没有数据,则等待生产者放入数据
  if(!bFull)
  {
   try
   {
    wait();
   }
   catch (Exception e)
   {
    e.printStackTrace();
   }
  }
  //改变是否取走数据得状态标记的值
  bFull = false;
  //通知生产者,放入数据
  notify();
  //返回数据,消费者取走数据
  return value;
}
//生产者放入数据的方法
synchronized void  set(int intValue)
{
  //如果数据不是满的,也就是数据被消费者取走了,则放入数据
  if(!bFull)
  {
   //生产者放入数据
   this.value = intValue;
   //改变数据是否被取走得标记
   bFull = true;
   //通知消费者来取数据
   notify();
  }
  //如果数据是满的,也就是消费者还没哟取数据,则等待消费折取走数据
  try{
   wait();
  }
  catch(Exception e){
   e.printStackTrace();
  }
}
}

//生产者类---情报员
class Producer extends Thread
{
MyQueue q;
Producer(MyQueue q)
{
  this.q = q;
}
public void run()
{
  for(int i=0;i<10;i++)
  {
   q.set(i);
   System.out.println("set==="+i);
  }
}
}

//消费者类 ---情报员
class Consumer extends Thread
{
MyQueue q;
Consumer(MyQueue q)
{
  this.q = q;
}
public void run()
{
  while(true)
  {
   System.out.println("get====="+q.get());
  }
}
}

>>7终止线程得方法:1变量控制
public class TestThread
{
public static void main(String[] args)
{
  Consumer c = new Consumer();
  c.start();
  int index =0;
  while(true){
   if(index++==500)
   {
   c.stopThread();//改变while循环的变量条件
    break;  //终止线程
   }
   System.out.println("main名字:"+Thread.currentThread().getName()+"index===="+index);
  }
  //程序结束输出
  System.out.println("main  exit()");
}
}
class Consumer extends Thread
{
//while循环的条件变量
private boolean bStop = false;

public void run()
{
  while(!bStop)
  {
   System.out.println("子线程名字:"+getName());
  }
}
//关闭线程的方法:改变while循环变量得条件
public void stopThread()
{
this.bStop  = true;
}
}

>>8带有wait方法的线程关闭方法2 :interrupt方法

public class TestThread
{
public static void main(String[] args)
{
  Consumer c = new Consumer();
  c.start();
  int index =0;
  while(true){
   if(index++==500)
   {
   c.stopThread();//改变while循环的变量条件 终止线程
    c.interrupt(); //关闭线程
    break;

   }
   System.out.println("main名字:"+Thread.currentThread().getName()+"index===="+index);
  }
  //程序结束输出
  System.out.println("main  exit()");
}
}
class Consumer extends Thread
{
//while循环的条件变量
private boolean bStop = false;
//wait方法一定要在静态方法或者静态块中
public synchronized void run()
{
  while(!bStop)
  {
   try{
    wait();//带有wait
   }
   catch(InterruptedException e)
   {
    //异常处理
    if(bStop){
     return ;
    }
   }
   System.out.println("子线程名字:"+getName());
  }
}
//关闭线程的方法:改变while循环变量得条件
public void stopThread()
{
  this.bStop  = true;
}
}

>>一个完整的内部类例子
//内部类实现
public class SellTicket
{
private  int tickets=100;
public SellTicket ()
{}
//内部类,继承Thread
class Sellor extends Thread
{
//重写run方法
  public void run()
  {
   synchronized(this)
   {
    while(tickets>0)
    {
    
     System.out.println(Thread.currentThread().getName()+"sells  tickets====="+tickets);
     tickets--;
    }
   }
  }
//方法返回值为Thread,返回内部类自己的实体对象(因为内部类已经继承了Thread或者实现了Runnable接口)
  public Thread getSellor()
  {
   return new Sellor();
  }

}
public static void main(String[] args)
{
  SellTicket sell = new SellTicket();
//调用内部类的线程并启动run方法
  sell.new Sellor().getSellor().start();
  
}
}
>>关于重写run方法的理解
一个类继承自Thread,此时可以不重写run方法,就等于使用Thread的run方法,run(){}方法是空的,所以没有意义但是不会出错;
一个类实现了 Runnable接口必须实现run方法,这是实现接口要求的,否则会出错

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值