线程及问题解决

推荐使用第二种,用接口实现

package 线程;
//创建线程方式一:继承Thread类,重写run()方法,调用start
//总结:注意线程开启不一定立即执行,有CPU调度执行。
//开启了会同时执行。是交替的,因为同一时间只能做一件事情,电脑是单核的
public class Thread1 extends Thread {
   @Override
   public void run() {
     //run方法线程体
       for (int i = 0; i < 20; i++) {
           System.out.println("我在干饭————"+i);
      }
  }

   public static void main(String[] args){
       //main线程,主线程
       //创建一个线程对象
       Thread1 thread1 = new Thread1();
       //调用start()方法开启线程
       thread1.start();

       for (int i = 0; i < 200; i++) {
           System.out.println("我在睡觉----"+i);
      }
  }
}

创建方式二

实现Runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法。

package 线程;

public class Runnable1 implements java.lang.Runnable {
   @Override
   public void run(){
       for (int i = 0; i < 200; i++) {
           System.out.println("干饭"+i);
      }
  }
//区别:一个是继承类,一个是实现接口
   /*
   1.实现接口,重写run方法
   2.执行线程需要丢入,接口的实现类
   3.调用start方法
    */
   public static void main(String[] args) {
       Runnable1 runnable1 = new Runnable1();
       Thread thread = new Thread(runnable1);
       thread.start();
       for (int i = 0; i < 30; i++) {
           System.out.println("睡觉"+i);
      }
  }
}

总结:

继承Thread类:1.子类继承具备多线程的能力

2.启动线程:子类对象.start()

3.不建议使用:避免oop单继承局限性。

 

实现Runnable接口:1.实现Runnable具有多线程能力

2.启动线程:传入目标对象+Thread对象.start()

3.推荐使用;避免单继承局限性,灵活方便,方便同一个对象被多线程使用。

 

 

 

package 线程;

public class Ticket implements Runnable {
   int ticketNub = 20;

   @Override
   public void run() {
       //模拟抢票
       while (true) {
           if (ticketNub == 0) {
               break;
          }
           ticketNub--;
           System.out.println(Thread.currentThread().getName() + "抢到了第:" + ticketNub + "张票!");
           //Thread.currentThread() 获取线程本身
      }
  }


   public static void main(String[] args) {


       Ticket ticket = new Ticket();
       /*Thread thread = new Thread(ticket,"小明");
       Thread thread = new Thread(ticket,"小红");
       Thread thread = new Thread(ticket,"黄牛");
       thread.start();*/
       new Thread( ticket,"小明").start();
       new Thread( ticket,"小红").start();
       new Thread( ticket,"黄牛").start();
      //三个线程
       /*
       多个线程去调用一个对象(操作同一个资源时),线程不安全,数据紊乱。
       并发问题。
        */
  }
}

//sleep(时间)指定当前线程阻塞的毫秒数; 睡觉

并发:同一个对象被多个线程同时操作。

解决办法:队列 + 锁。

每个对象都有一个锁。

锁机制:synchronized

缺点:性能差

优点:安全性高

package 线程;

public class Ticket implements Runnable {
   int ticketNub = 20;

   @Override
   public synchronized void run() {
       //模拟抢票
       while (true) {
           if (ticketNub == 0) {
               break;
          }
           ticketNub--;
           System.out.println(Thread.currentThread().getName() + "抢到了第:" + ticketNub + "张票!");
           //Thread.currentThread() 获取线程本身
      }
  }


   public static void main(String[] args) {


       Ticket ticket = new Ticket();
       /*Thread thread = new Thread(ticket,"小明");
       Thread thread = new Thread(ticket,"小红");
       Thread thread = new Thread(ticket,"黄牛");
       thread.start();*/
       new Thread( ticket,"小明").start();
       new Thread( ticket,"小红").start();
       new Thread( ticket,"黄牛").start();
      //三个线程
       /*
       多个线程去调用一个对象(操作同一个资源时),线程不安全,数据紊乱。
       并发问题。
        */
  }
}

就在抢票哪里加了一个关键字:synchronized

难点:锁谁。一般锁有变化的那个。有增删改的。

 
posted @ 2022-07-31 22:08  锦书南辞  阅读(41)  评论(0)    收藏  举报