多线程相关概念

package module;
public class ClassRoom1 {
    public static void main(String[] args) {
    MYthread my = new MYthread();
    Thread t1 = new Thread(my,"窗口1-");
    Thread t2 = new Thread(my,"窗口2-");
    Thread t3 = new Thread(my,"窗口3-");
    t1.start();
    t2.start();
    t3.start();
    }
}

并行:指的是多个任务在多个CPU上执行

并发:指的是多个任务在CPU上交通执行

进程与线程:

进程:进程就是操作系统正在运行的程序,所以进程也就是正在运行的程序

线程:是程序运行的基本单元,当系统操作一个一个程序的时候会建立一个进程,该进程必须建立一个线程,这个线程被称为主线程,在运行程序的过程中每一个程序至少有一个线程,

多线程

指的是一个硬件或者软件在同一时间支持多条线程,,好处提升程序的效率

多线程的创建方式:

java.lang.Thread,是线程类,可以用来创建线程处理任务使用,两个比较重要的方法:

public void run():线程执行任务的方法:是线程启动后第一个执行的方法。

public void start() 启动线程的方法,线程对象调用之后会执行run方法。

线程类

package module;
public class ClassRoom1 {
    public static void main(String[] args) {
        MYthread my = new MYthread();
        my.start();
        for (int i = 0; i < 200; i++){
            System.out.println("main方法开始执行了");
        }
    }
}

main方法

package module;

public class MYthread extends Thread{//继承线程类

    @Override
    public void run() {//重写thread里面的run方法
       for (int i = 0; i < 200; i++) {
           System.out.println("线程开始执行了");
       }
    }
}

创建方式二:

实现Runable接口;

线程类:

package module;
public class MYthread implements Runnable{//实现Runable接口
    @Override
    public void run() {//重写thread里面的run方法
       for (int i = 0; i < 200; i++) {
           System.out.println("线程开始执行了");
       }
    }
}

package module;
public class ClassRoom1 {
    public static void main(String[] args) {
        MYthread my = new MYthread();//创建线程任务对象
       Thread t1 = new Thread(my);//创建线程对象
       t1.start();//开启线程
        for (int i = 0; i < 200; i++){
            System.out.println("main方法开始执行了");
        }
    }
}

运行结果:

实现与继承的优缺点:

继承:优点:编程简单可以直接使用Thread类的方法

缺点:只能单继承,扩展性差

实现:优点:可以多实现,扩展性大

缺点:代码繁琐不能直接使用Thread类里面的方法。

Thread常用方法

String getName():给线程取名字。

void setName(String name),通过构造方法给线程取名字,

public void Thread currenThread():获取当前线程对象:

public static void sleep(long time):指定线程休眠时间。

package module;
public class MYthread implements Runnable{//实现Runable接口
    @Override
    public void run() {//重写thread里面的run方法
       for (int i = 0; i < 200; i++) {
         String name = Thread.currentThread().getName();//获取线程名称
           System.out.println(name+i);
       }
    }
}
package module;
public class ClassRoom1 {
    public static void main(String[] args) {
        MYthread my = new MYthread();//创建线程任务对象
       Thread t1 = new Thread(my,"新线程");//指定执行任务的线程
       t1.start();//开启线程

        try {
            Thread.sleep(100);//指定线程休眠的时间
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        for (int i = 0; i < 200; i++){
            //获取main方法里面线程的名称
            System.out.println(Thread.currentThread().getName()+" "+i);
        }
    }
}

线程安全问题:

线程类:

package module;
public class MYthread implements Runnable{
    private int ticket=100;
    @Override
    public void run() {
      while(true){
          if(ticket>0){
         String name = Thread.currentThread().getName();
              System.out.println(name+"正在买第:"+ticket+"张票");
              ticket--;
          }
      }

    }
}
package module;
public class ClassRoom1 {
    public static void main(String[] args) {
    MYthread my = new MYthread();
    Thread t1 = new Thread(my,"窗口1-");
    Thread t2 = new Thread(my,"窗口2-");
    Thread t3 = new Thread(my,"窗口3-");
    t1.start();
    t2.start();
    t3.start();
    }
}

可以看到运行的时候出现多次重复的票数;解决:

同步代码块:

package module;
public class MYthread implements Runnable {
    private int ticket = 100;
    private Object lock = new Object();

    @Override
    public void run() {
        for (int i = 1; i <= ticket; i++)  {
            synchronized (lock) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                if (ticket > 0) {
                    String name = Thread.currentThread().getName();
                    System.out.println(name + "正在买第:" + ticket + "张票");
                    ticket--;
                }
            }

        }
    }
}

添加同步代码块之后在去运行main方法就不会出现卖一样的票数了

同步方法:

package module;
public class MYthread implements Runnable {
    private int ticket = 100;

    @Override
    public void run() {
      while (true) {
          mathod();
      }

    }
    public synchronized  void mathod() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        if (ticket > 0) {
            String name = Thread.currentThread().getName();
            System.out.println(name + "正在买第:" + ticket + "张票");
            ticket--;
        }
    }
    }

Lock锁机制:

package module;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MYthread implements Runnable {
    private int ticket = 100;
    Lock lock = new ReentrantLock();
    @Override
    public void run() {
      while (true) {
          lock.lock();
          if (ticket <=0) {
              break;
          }
          if (ticket > 0) {
              try {
                  Thread.sleep(100);
              } catch (InterruptedException e) {
                  throw new RuntimeException(e);
              }
              String name = Thread.currentThread().getName();
              System.out.println(name + "正在买第:" + ticket + "张票");
              ticket--;
          }
          lock.unlock();
      }

    }
}

运行main方法都没有重票的以上几种方法是解决重票的问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值