Java 中的多线程-两种创建方式,定时器的应用,线程的安全问题可以用银行转账来说明

时间:2022-11-03 20:42:53

/*
   * Thread thread = new Thread() // 第一种方法new 它的子类 {
   *
   * @Override public void run() { while (true) { try {
   * Thread.sleep(1000); } catch (InterruptedException e) {
   * e.printStackTrace(); }
   * System.out.println(Thread.currentThread().getName());
   * System.out.println("------------------------------");
   * System.out.println(this.getName()); } } }; thread.start();
   *
   * Thread thread2 = new Thread(new Runnable() // new 传一个runnable
   * 这种方式更面向对象些 {
   *
   * @Override public void run() { while (true) { try {
   * Thread.sleep(1000); } catch (InterruptedException e) {
   * e.printStackTrace(); }
   * System.out.println(Thread.currentThread().getName());
   * System.out.println("------------------------------"); } } });
   *
   * thread2.start();
   */

 

  定时器的写法

  Timer timer = new Timer();   

  timer.schedule(new TimerTask()   {    

 @Override   
  public void run()    {
   System.out.println("bombing");   

 }  

 }, 10000,3000);

  while (true)   {    

System.out.println(new Date().getSeconds());  

 try    {     Thread.sleep(1000);    }    

catch (InterruptedException e)   

 {    

  e.printStackTrace();  

  }   }

 

定时器的每隔2秒与4秒交替出现一句话

private static int count = 0;

 public static void main(String[] args)  {   class myTimerTask extends TimerTask   {    @Override    public void run()    {     count = (count + 1) % 2;     System.out.println("bombing");     new Timer().schedule(new myTimerTask(), 2000 + 2000 * count);    }   }

  Timer timer = new Timer();   timer.schedule(new myTimerTask(), 2000);

  while (true)   {    System.out.println(new Date().getSeconds());    try    {     Thread.sleep(1000);    }    catch (InterruptedException e)    {     e.printStackTrace();    }   }

 

 线程的安全

package cn.itcast.day5.thread;

public class TraditionThreadSynchronized {  public static void main(String[] args)  {   new TraditionThreadSynchronized().init();  }

 private void init()  {   final Outputer outputer = new Outputer();   new Thread(new Runnable()   {    @Override    public void run()    {     while (true)     {      try      {       Thread.sleep(0);      }      catch (InterruptedException e)      {       e.printStackTrace();      }      outputer.output("peterpeng");     }    }   }).start();

  new Thread(new Runnable()   {    @Override    public void run()    {     while (true)     {      try      {       Thread.sleep(0);      }      catch (InterruptedException e)      {       e.printStackTrace();      }      outputer.output2("yangyang");     }    }   }).start();  }

 static class Outputer  {   String xxx = "";

  public void output(String name)   {    int len = name.length();    synchronized (xxx) // 这里就是用来一个线程跑完再跑另一个线。xxx:也就可以用this,但最好的方法是下面的写法         // 一定要是同一个对象,不能用name因为是两个对象,而outputer是同一个对象,如果new         // outputer().output("yanyang")又会出问题,因为这样两个名不一样,是不同的对象    {     for (int i = 0; i < len; i++)     {      System.out.print(name.charAt(i));     }     System.out.println();    }   }

  public synchronized void output1(String name)// 这里是线程安全的写法,一定只能有一个synchronized,否则会死锁   {    int len = name.length();    {     for (int i = 0; i < len; i++)     {      System.out.print(name.charAt(i));     }     System.out.println();    }   }

  public static synchronized void output2(String name)// 这里是线程安全的写法,一定只能有一个synchronized,否则会死锁   {    int len = name.length();    {     for (int i = 0; i < len; i++)     {      System.out.print(name.charAt(i));     }     System.out.println();    }   }

  // 说明如果调用output 与output2   // 又会出问题,因为两个又不是同一个对象了。要解决这个问题,可以升级到字节码在output中把xxx换成 Output.class就可以了  } }