首页 > 其他分享 >线程安全&&定时器总结

线程安全&&定时器总结

时间:2023-12-28 20:57:57浏览次数:25  
标签:Tickets 定时器 Thread start 线程 && new public

总结

线程

线程:执行的独立代码
线程执行是靠cpu分配时间片,同一个时间片上只能执行一个线程
线程的状态:

  1. 新建
  2. 就绪
  3. 运行
  4. 阻塞
  5. 死亡

Thread:多线程的类

  1. currentThread()
  2. getName() ,setName()
  3. sleep()

实现多线程的方式
1. 继承Thread,重写run
2. 实现Runnable,重写run

实现线程安全的三种方式

线程的执行是靠cpu分配时间片
存在一票多卖:多个线程同时访问一个数据,同一个数据被访问多次,存在线程安全问题
线程安全问题是怎样发生:线程要执行的代码还没有全部执行完,另一个线程有开是执行
怎样来解决这个线程安全问题:保证线程要执行的代码全部要执行完毕

synchronized (参数:引用类型,所有的线程对象都能共享的(static修饰,字节码对象) )

  1. 同步代码块:将同步代码快作为一个整体

    继承Thread,重写run

    public class Tickets extends Thread{
        private static int count = 1;
    
        public Tickets() {
        }
    
        public Tickets(String name) {
            super(name);
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 30; i++) {
                synchronized (this.getClass()) {
                    if(count <= 30) {
                        // 获取当前线程的名
                        String name = Thread.currentThread().getName();
                        System.out.println(name + "窗口:卖出第" + count + "张票");
                        count++;
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }
    }
    
    // 测试类
    public class TicketsTest {
        public static void main(String[] args) {
            Tickets t1 = new Tickets("花泽");
            Tickets t2 = new Tickets("龙泽");
            Tickets t3 = new Tickets("波多野蘋蘋");
            t3.setPriority(Thread.MAX_PRIORITY);
            t1.start();
            t2.start();
            t3.start();
        }
    }
    

    实现Runnable,重写run

    public class Tickets implements Runnable {
        private int count = 1; // 可以是实例变量,也可以是类变量
        private ReentrantLock lock = new ReentrantLock(true);
    
        // 使用同步代码块来处理线程不安全的问题
        public void run() {
            for (int i = 0; i < 30; i++) {
                synchronized (this.getClass()) { // this:当前对象
                    if (count <= 30) {
                        String name = Thread.currentThread().getName(); // 获取当前线程的名字
                        System.out.println(name + "窗口:卖出第" + count + "张票");
                        count++;
                    }
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    
    // 测试类
    public class TicketsTest {
        public static void main(String[] args) {
            // 1、创建Runnable对象
            Tickets tickets = new Tickets();
            // 2、创建线程
            Thread t1 = new Thread(tickets, "蘋蘋1号");
            Thread t2 = new Thread(tickets, "蘋蘋2号");
            Thread t3 = new Thread(tickets, "蘋蘋3号");
            // 3、启动线程
            t1.start();
            t2.start();
            t3.start();
        }
    }
    
  2. 同步方法:用synchronized 修饰方法

    继承Thread,重写run

    public class Tickets2 extends Thread{
        private static int count = 1;
    
        public Tickets2() {
        }
    
        public Tickets2(String name) {
            super(name);
        }
    
        // 设计一个买票的方法
        public static synchronized void sale() { // 这个就是同步方法,同步实例方法的锁默认是this,同步类方法的锁是当前类的字节码对象
                if (count <= 30) {
                    // 获取当前线程的名
                    String name = Thread.currentThread().getName();
                    System.out.println(name + "窗口:卖出第" + count + "张票");
                    count++;
                }
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 30; i++) {
                sale();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    
    public class Tickets2Test {
        public static void main(String[] args) {
            Tickets2 t1 = new Tickets2("花泽");
            Tickets2 t2 = new Tickets2("龙泽");
            Tickets2 t3 = new Tickets2("波多野蘋蘋");
            t3.setPriority(Thread.MAX_PRIORITY);
            t1.start();
            t2.start();
            t3.start();
        }
    }
    

    实现Runnable,重写run

    public class Tickets implements Runnable {
        private int count = 1; // 可以是实例变量,也可以是类变量
        private ReentrantLock lock = new ReentrantLock(true);
    
        // 使用同步方法
        public synchronized void sale() {
            if (count <= 30) {
                String name = Thread.currentThread().getName(); // 获取当前线程的名字
                System.out.println(name + "窗口:卖出第" + count + "张票");
                count++;
            }
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 30; i++) {
                sale();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    
    // 测试类
    public class TicketsTest {
        public static void main(String[] args) {
            // 1、创建Runnable对象
            Tickets tickets = new Tickets();
            // 2、创建线程
            Thread t1 = new Thread(tickets, "蘋蘋1号");
            Thread t2 = new Thread(tickets, "蘋蘋2号");
            Thread t3 = new Thread(tickets, "蘋蘋3号");
            // 3、启动线程
            t1.start();
            t2.start();
            t3.start();
        }
    }
    
  3. 同步锁:ReentrantLock,lock():上锁,unlock():解锁

    继承Thread,重写run

    public class Tickets3 extends Thread{
        // 创建同步锁
        private  static ReentrantLock lock = new ReentrantLock(true); // 不带公平机制
        private static int count = 1;
    
        public Tickets3() {
        }
    
        public Tickets3(String name) {
            super(name);
        }
    
    
        @Override
        public void run() {
            // 使用同步锁
            for (int i = 0; i < 30; i++) {
                    // 上锁
                    lock.lock();
                    try {
                        if (count <= 30) {
                            // 获取当前线程的名
                            String name = Thread.currentThread().getName();
                            System.out.println(name + "窗口:卖出第" + count + "张票");
                            count++;
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }finally {
                        // 释放锁
                        lock.unlock();
                    }
            }
        }
    }
    
    public class Tickets3Test {
        public static void main(String[] args) {
            Tickets3 t1 = new Tickets3("花泽");
            Tickets3 t2 = new Tickets3("龙泽");
            Tickets3 t3 = new Tickets3("波多野蘋蘋");
            t3.setPriority(Thread.MAX_PRIORITY);
            t1.start();
            t2.start();
            t3.start();
        }
    }
    

    实现Runnable,重写run

    public class Tickets implements Runnable {
        private int count = 1; // 可以是实例变量,也可以是类变量
        private ReentrantLock lock = new ReentrantLock(true);
    
        // 使用同步锁
        @Override
        public void run() {
            for (int i = 0; i < 30; i++) {
                // 上锁
                lock.lock();
                try {
                    if (count <= 30) {
                        String name = Thread.currentThread().getName(); // 获取当前线程的名字
                        System.out.println(name + "窗口:卖出第" + count + "张票");
                        count++;
                    }
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }finally {
                    // 解锁
                    lock.unlock();
                }
            }
    
        }
    }
    
    // 测试类
    public class TicketsTest {
        public static void main(String[] args) {
            // 1、创建Runnable对象
            Tickets tickets = new Tickets();
            // 2、创建线程
            Thread t1 = new Thread(tickets, "蘋蘋1号");
            Thread t2 = new Thread(tickets, "蘋蘋2号");
            Thread t3 = new Thread(tickets, "蘋蘋3号");
            // 3、启动线程
            t1.start();
            t2.start();
            t3.start();
        }
    }
    

Timer:定时器(也可作为守护线程)

定时器:在指定时间做指定事情,比如:闹钟

在开发定时器的作用:1、定时发邮件 2、定时备份 3、定时写日志

就是学习一个类:Timer:定时器类,做定时任务的

TimerTask:定时任务,另外一个线程

// 定时任务
import java.util.TimerTask;

/**
 * 写一个定时任务
 */
public class SayHi extends TimerTask {
    @Override
    public void run() {
        System.out.println("hello boys and girls......");
    }
}
// 测试类
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;

public class TimerDemo {
    public static void main(String[] args) {
        // 创建一个定时器
        Timer timer = new Timer(); // 创建了一个线程
        // 调用其他线程:schedule()
        SayHi sayHi = new SayHi();
//        timer.schedule(sayHi,2000); // 2秒后执行定时任务,一次性任务
//        timer.schedule(sayHi,2000,3000); // 周期性的任务
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.SECOND, -10);
        Date date = cal.getTime();
//        timer.schedule(sayHi,date,3000);

        timer.scheduleAtFixedRate(sayHi,date,3000);
    }
}

标签:Tickets,定时器,Thread,start,线程,&&,new,public
From: https://www.cnblogs.com/JunYuanStudy/p/17933550.html

相关文章

  • 实现线程的三种方式
    一、继承Thread类Thread类中创建线程最重要的两个方法为:publicvoidstart();publicvoidrun();采用Thread类创建线程,用户只需要继承Thread,覆盖Thread中的run方法,父类Thread中的run方法没有抛出异常,那么子类也不能抛出异常,最后采用start启动线程即可。【示例......
  • Java多线程:数据一致性问题及解决方案
    引言在面向对象的编程语言Java中,多线程编程是一个强大的工具,可以使我们能够构建高效率和高并发的应用程序。然而,多线程环境下的数据共享也带来了数据一致性的挑战。在本文中,我们将探讨Java多线程中的数据一致性问题,并提出几种解决方案。数据一致性问题当多个线程同时对共享资源进行......
  • 摩尔线程S2000GPU环境配置
    引子书接上文,这边再来一个国产AI芯片的环境配置,OK,让我们开始吧。一、安装系统Ubuntu20.04.11、USB光盘刻录系统2、安装3、系统主板BIOS开启Above4G及ResizeBAR功能4、命令lspci|grep123二、安装GPU环境1、安装驱动程序(服务器Ip:10.231.6.92,账号:nick密码:123456)......
  • 深入探究多线程中的虚假唤醒现象--从生产者消费者问题到高级解决方案的全方位解读
    文章目录生产者和消费者问题虚假呼唤问题解决方案线程之间的虚假唤醒问题常出现在多线程编程中。我看国内很多教程都解释的稀里糊涂的,所以打算写一篇博客好好絮叨絮叨。首先看一下线程虚假唤醒的定义:多线程环境下,有多个线程执行了wait()方法,需要其他线程执行notify()或者notifyAl......
  • 死锁、内部碎片、外部碎片、多进程/多线程、服务器高并发、集群
    死锁:两个(多个)线程互相等待对方数据的过程1.死锁产生条件(解决办法):......
  • Qt 中的多线程 02:移动工作对象到子线程中
    Qt中的多线程除了通过继承QThread类,然后重写虚函数run()之外还有另一种方案:将要执行的复杂操作,放在一个继承自QObject的类中,然后使用QObject::moveToThread(QThread*)函数将工作对象的移动到创建的子线程中去执行。工作对象类该类继承自QObject主要是用来实现一些耗......
  • Java线程池ThreadPoolExecutor源码解析
    Java线程池ThreadPoolExecutor源码解析1.ThreadPoolExecutor的构造实现以jdk8为准,常说线程池有七大参数,通常而言,有四个参数是比较重要的publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,lon......
  • Java多线程:状态转移详解
    Java中的线程在其生命周期内会经历不同的状态。理解这些状态以及它们之间的转换对于掌握多线程编程至关重要。本文将详细介绍Java线程的状态以及它们之间的转换机制。线程生命周期状态根据Java语言规范和java.lang.Thread.State枚举定义,线程的状态主要分为以下几种:新建(NEW):创建后尚......
  • [BOM]定时器
    定时调用 setInterval//开启定时器:第一个参数是回调函数(必须),第二个参数是毫秒//返回值表示是这个页面的第几个定时器(从1开始数)vartimer=setInterval(function(){console.log('一秒!');},1000);console.log(timer);//异步语句......
  • Java第十八课_线程和网络
    1.线程线程的休眠publicstaticvoidmain(String[]args){//线程的休眠//第一种方式(不推荐):try{Thread.sleep(3000);//毫秒}catch(InterruptedExceptione){e.printStackTrace();}......