线程的学习

一,实现线程有两种方式

方式1:继承Thread类

1:定义一个类MyThread继承Thread类

2:在MyThread卖中重写run()方法

3:创建MyThread类的对象

4∶启动线程 Thread类中获取和设苴线程名称的方法

void setName(String_name):_将此线程的名称更改为等于参数name

String getName():返回此线程的名称

首先定义一个类MyThread继承Thread类

package com.ithema_01;

public class MyThread extends Thread{
    public MyThread(){
    }
    public MyThread(String name){
        super(name);
    }
    @Override
    public void run() {
        for(int x = 0; x < 100; x++){
            System.out.println(getName() + ":" + x);
        }
    }
}

测试类

public class MyThreadDemo {
    public static void main(String[] args) {
//        MyThread my1 = new MyThread();
//        MyThread my2 = new MyThread();
      /*  my1.setName("dd");
        my2.setName("EE");*/
        //Thread(String name)
//        MyThread my1 = new MyThread("ss");
//        MyThread my2 = new MyThread("gg");
//
//        //void start() 导致此线程开始执行;java须立即调用此线程的run方法
//        my1.start();
//        my2.start();
//        static Thread currentThread () 返回对当前正在执行的线程对象的引用
        System.out.println(
                Thread.currentThread().getName());
    }
}

方式2:实现Runnable接口


  1 :定义—个类MyRunnable实现Runnable接口
  2:在MyRunnable类中重写run()方法
  3:创建MyRunnable类的对象
  4:创建Thread类的对象,把MyRunnable对象作为构造方法的参数
  5:启动线程

定义—个类MyRunnable实现Runnable接口

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for(int x = 0; x < 100; x++){
            System.out.println(Thread.currentThread().getName() + ":" + x);
        }
    }
}
测试类

public class MyRunnableDemo {
    public static void main(String[] args) {
        //创建MyRunnable类的对象
        MyRunnable my = new MyRunnable();

        //创建Thread类的对象,把MyRunnable对象作为构造方法的参数
//        Thread t1 = new Thread(my);
//        Thread t2 = new Thread(my);
        //Thread (Runnable target, String name)
        Thread t1 = new Thread(my,"gg");
        Thread t2 = new Thread(my,"qq");
        //启动线程
        t1.start();
        t2.start();
    }
}


二,线程优先级

   Thread类中设置和获取线程优先级的方法


       public final void setPriority(int newPriority):更改此线程的优先级
       public final int getPriority():返回此线程的优先级

定义TreadPriority类


public class TreadPriority extends Thread{
    public TreadPriority(String name) {
        super(name);
    }

    @Override
    public void run() {
        for(int x = 0; x < 100; x++){
            System.out.println(getName() + ":" + x);
        }
    }
}

定义测试类

public class TreadPriorityDemo {
    public static void main(String[] args) {
        TreadPriority tp1 = new TreadPriority("dd");
        TreadPriority tp2 = new TreadPriority("ff");
        TreadPriority tp3 = new TreadPriority("gg");

        // public final void setPriority(int newPriority):更改此线程的优先级
      /*  System.out.println(tp1.getPriority());//5
        System.out.println(tp2.getPriority());//5
        System.out.println(tp3.getPriority());//5
        */
      //public final void setPriority(int newPriority):更改此线程的优先级
     /*   System.out.println(Thread.MAX_PRIORITY);//10
        System.out.println(Thread.MIN_PRIORITY);//1
        System.out.println(Thread.NORM_PRIORITY);//5*/
      //设置正确的优先级
        tp1.setPriority(1);
        tp2.setPriority(10);
        tp3.setPriority(1);

        tp1.start();
        tp2.start();
        tp3.start();
    }
}

三,线程控制

1,void setDaemon (boolean on):将此线程标记为守护线程,当运行的线程都是守护线程时,Javo虚拟机将退出

继承类:
public class ThreadDaemon extends Thread {
    public ThreadDaemon(String name) {
        super(name);
    }

    @Override
    public void run() {
        for(int x = 0; x < 100; x++){
            System.out.println(getName() + ":" + x);
        }
    }
}

测试类:
public class ThreadDaemonDemo {
    public static void main(String[] args) {
        ThreadDaemon td1 = new ThreadDaemon("张飞");
        ThreadDaemon td2 = new ThreadDaemon("关羽");
        //设置主线程为刘备
        Thread.currentThread().setName("刘备");
        //设置守护线程
        td1.setDaemon(true);
        td2.setDaemon(true);

        td1.start();
        td2.start();
        for(int x = 0; x < 10; x++){
            System.out.println(Thread.currentThread().getName() + ":" + x);
        }
    }

2,void join():等待这个线程死亡

继承类:
public class ThreadJoin extends Thread {
    public ThreadJoin(String name) {
        super(name);
    }

    @Override
    public void run() {
        for(int x = 0; x < 100; x++){
            System.out.println(getName() + ":" + x);
        }
    }
}
测试类:
public class ThreadJoinDemo {
    public static void main(String[] args) throws InterruptedException {
        ThreadJoin tj1 = new ThreadJoin("康熙");
        ThreadJoin tj2 = new ThreadJoin("老四");
        ThreadJoin tj3 = new ThreadJoin("老八");

        tj1.start();
        tj1.join();

        tj2.start();
        tj3.start();
    }
}

3,static void sleep(Long willis)。使当前正在执行的线程停留〈暂停执行)指定的亳秒数

继承类:
public class ThreadSleep extends Thread {
    public ThreadSleep(String name) {
        super(name);
    }

    @Override
    public void run() {
        for(int x = 0; x < 100; x++){
            System.out.println(getName() + ":" + x);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
实现类:
public class ThreadSleepDemo {
    public static void main(String[] args) {
        ThreadSleep ts1 = new ThreadSleep("曹操");
        ThreadSleep ts2 = new ThreadSleep("孙权");
        ThreadSleep ts3 = new ThreadSleep("刘备");

        ts1.start();
        ts2.start();
        ts3.start();

    }
}

四,线程安全类

 StringBuffe , Vector ,Hashtable

public class ThreadDemo {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        StringBuilder sb2 = new StringBuilder();

        Vector<String> v = new Vector<String>();
        ArrayList<String> array = new ArrayList<String>();

        Hashtable<String,String> ht = new Hashtable<String, String>();
        HashMap<String,String> hm = new HashMap<String, String>();

        //static <T> list<T> synchronizedList(List<T> list)返回有指定列表支持的同步(线程安全)列表
        List<String> list = Collections.synchronizedList(new ArrayList<String>());//将线程不安全集合转为线程安全集合
    }
}

 五,案例

 需求:
    某电影院目前正在上映国产大片,共有10o张票,而它有3个窗口卖票,请设计一个程序模拟该电影3院卖票

思路:
  1:定义一个类sellTicket实现Runnable接口,里面定义一个成员变量: private int tickets = 100;
  2:在seLLTicket类中重写run()方法实现卖票,代码步骤如下
    A:判断票数大于e,就卖票,并告知是哪个商口卖的
    B:卖了票之后,总票救要诚1
    C:票没有了,也可能有人来间,所以这里用死循环让卖票的动作一直执行
  3:定义—个测试类selLTicketDemo,里面有main方法,代码步彩如下
    A:创建sellTicket类的对象
    B:创建三个Thread类的对象,把sellTicket对象作为构造方法的参数,并给出对应的窗口名称
    c:启动线程

继承类:
public class SellTicket implements Runnable {
    private int tickets = 100;
    private Lock lock = new ReentrantLock();
    @Override
    public void run() {
        while (true) {
                  try {
                      lock.lock();
                      if (tickets > 0) {
                          //使当前正在执行的线程停留
                          try {
                              Thread.sleep(100);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          System.out.println(Thread.currentThread().getName() + "正在售卖" + tickets + "张票");
                          tickets--;
                  }
                }finally {
                      lock.unlock();
                  }
            }
        }
    }
测试类:
public class SellTicketDemo {
    public static void main(String[] args) {
    //创建sellTicket类的对象
        SellTicket st = new SellTicket();
        //创建三个Thread类的对象,把sellTicket对象作为构造方法的参数,并给出对应的窗口名称
        Thread t1 = new Thread(st,"窗口一");
        Thread t2 = new Thread(st,"窗口二");
        Thread t3 = new Thread(st,"窗口三");
        //启动线程
        t1.start();
        t2.start();
        t3.start();
    }
}

六,生产者消费者问题

 方法:

 案例讲解:买牛奶

  生产者消费者案例中包含的类,
    1:奶箱类(Box):定义一个成员变量,表示第x瓶奶,提供存储牛奶和获取牛奶的操作
    2:生产者类(Producer):实现Runnable接口,重写run()方法,调用存储牛奶的操作
    3:消费者类(Customer)。实现Runnable接口,重写run()方法,调用获取牛奶的操作
    4:测试类(BoDemo):里面有main方法,main方法中的代码步骤如下
       A:创建奶箱对象,这是共亨数据区域
       B:创建生产者对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用存储牛奶的操作
       c:创建消费者对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用获取牛奶的操作
       D:创建2个线程对象,分别把生产者对象和消费者对象作为构造方法参数传递
       E:启动线程

Box类:
public class Box {
    //定义一个成员变量,表示第x瓶奶
    private int milk;
    //定义一个成员变量,表示奶箱状态
    private boolean state = false;

    //提供存储牛奶和获取牛奶的操作
    public synchronized void put(int milk){
        //如果有牛奶就等待消费
        if (state){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //如果没有牛奶,就生产牛奶
        this.milk = milk;
        System.out.println("送奶工将第" + this.milk + "瓶奶放入奶箱");
        //生产完毕之后。修改奶箱状态
        state = true;
        //唤醒其他的等待线程
        notifyAll();
    }
    public synchronized void get(){
        //如果没有牛奶就等待生产
        if(!state){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //有牛奶就拿
        System.out.println("生产者拿第" + this.milk + "瓶奶");
        //拿了之后。修改奶箱状态
        state = false;
        //唤醒其他的等待线程
        notifyAll();
    }
}


Producer类:
public class Producer implements Runnable {
    private Box b;
    public Producer(Box b){
        this.b = b;
    }
    @Override
    public void run() {
        for(int x = 1; x <= 5; x++){
           b.put(x);
        }
    }
}


Customer类:
public class Customer implements Runnable {
    private Box b;
    public Customer(Box b){
        this.b = b;
    }
    @Override
    public void run() {
       while (true){
           b.get();
       }
    }
}


测试类:
public class BoxDemo {
    public static void main(String[] args) {
        //创建奶箱对象,这是共亨数据区域
        Box b = new Box();
        //创建生产者对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用存储牛奶的操作
        Producer p = new Producer(b);
        //:创建消费者对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用获取牛奶的操作
        Customer c = new Customer(b);
        //创建2个线程对象,分别把生产者对象和消费者对象作为构造方法参数传递
        Thread t1 = new Thread(p);
        Thread t2 = new Thread(c);
        //启动线程
        t1.start();
        t2.start();
    }
}

七,问题解决

1,同步代码块解决数据安全问题

同步代码块
   锁多条语句操作共享数据,可以使用同步代码块实现
格式:
       synchronized(任意对象){
          多条语句操作共享数据的代码
       }
synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁
解决安全问题环境

   同步方法:
       就是把synchronized关键字加到方法上
  格式:
      修饰符 synchronized 返回值类型 方法名(方法参数){}
  同步方法的锁对象是什么呢?
     this
  同步静态方法:就是把synchronized关键字加到静态方法上
  格式:
     修饰符 static synchronized 返回值类型 方法名(方法参数{}
     锁对象:类名 + .class

2.lock锁

Lock中提供了获得锁和释放锁的方法
   void lock():获得锁
   void unLock():释放锁
Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化
   ReentrantLock():创建—个ReentrantLock的实例

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cqq00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值