Java 中传统多线程

Wesley13
• 阅读 521

@TOC

Java 中传统多线程

线程初识

线程的概念

当代操作系统中,可以独立并发执行的基本单元 轻量:占用系统资源极少 独立:操作系统可以独立调度和分派的基本单元 共享:共享进程中的资源

实现线程

继承Thread类,重写run方法 实现Runnable接口,实现run方法

package com.xc.test.threadtest;

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread threadA = new ThreadA();
        threadA.setName("ThreadA");
        threadA.start();

        ThreadB threadB = new ThreadB();
        Thread thread = new Thread(threadB);
        thread.start();

        while (true) {
            Thread.sleep(1000);
            System.out.println(3);
        }

    }
}

class ThreadA extends Thread {
    public void run() {
        while (true) {
            System.out.println(this.getName() + ":" + 2);
        }
    }
}

class ThreadB implements Runnable {
    public void run() {
        while (true) {
            System.out.println(4);
        }

    }
}

线程的生命周期

新建:线程刚刚创建完毕 可运行:启动线程后 运行:操作系统调度 阻塞/等待:等待某种资源或时间片到 消亡:退出run方法

常用API

类方法:针对当前运行线程 currentThread:获取当前运行线程的引用 yield:使得当前运行线程放弃当前时间片 sleep:使得当前运行线程休眠多少时间(单位是毫秒)

实例方法:针对指定线程 start:启动线程 setP:设置/获取线程优先级 setName/getName:设置/获取线程名称 setD:设置/获取线程的幽灵状态

线程同步

多线程共享数据的问题

多个线程并发访问同一个数据时,容易发生数据状态不稳定 使用锁机制完成线程同步(同-协同,步-调用顺序)

package com.xc.test.threadtest;

public class SysDemo {
    public static void main(String[] args) {
        Data data = new Data();
        new ThreadC(data).start();
        new ThreadC(data).start();
    }
}

class Data {
    int i;

    public void process() {
        System.out.println("Before:" + i);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        i++;
        System.out.println("After:" + i);
    }
}

class ThreadC extends Thread {
    Data data;

    public ThreadC(Data data) {
        this.data = data;
    }

    public void run() {
        super.run();
        while (true) {
            data.process();
        }
    }
}


Before:0
Before:0
After:1
After:2
Before:2
Before:2
After:3
Before:4
After:4

线程同步及实现机制

每个类一把锁,每个对象一把锁 只有获取锁的线程可以进入同步区域

class Data {
    int i;

    public void process() {
        synchronized (this) {//对象锁(任意对象),同步块
            System.out.println("Before:" + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            i++;
            System.out.println("After:" + i);
        }
    }
}


class Data {
    int i;

    public synchronized void process() {//对象锁(当前对象),同步方法
        System.out.println("Before:" + i);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        i++;
        System.out.println("After:" + i);
    }
}


Before:0
After:1
Before:1
After:2
Before:2
After:3
Before:3
After:4

线程间通讯

线程间通讯模型

wait:使当前线程进入指定对象的等待池 notify:从指定对象等待池中唤醒一个等待线程 notifyAll:从指定对象等待池中唤醒全部等待线程 只有获得该对象的锁后才可以调用上述方法

线程中通讯的实现

生产者:synchronized(obj){...;obj.notifyAll()} 消费者:synchronized(obj){obj.wait(),...;}

package com.xc.test.threadtest;

public class WnDemo {
    public static void main(String[] args) {
        Data2 data2 = new Data2();
        new Producer(data2).start();
        new Consumer(data2).start();
    }
}

class Data2 {
    int i;

    public void add() {
        synchronized (this) {
            i++;
            if (i % 5 == 0) {
                notifyAll();
            }
        }
    }

    public void sub() {
        synchronized (this) {
            try {
                this.wait();
            } catch (InterruptedException e) {
            }
        }
        System.out.println("Before:" + i);
        i++;
        System.out.println("After:" + i);
    }
}

class Consumer extends Thread {
    Data2 data;

    public Consumer(Data2 data) {
        this.data = data;
    }

    public void run() {
        while (true) {
            while (true) {
                data.sub();
            }
        }
    }
}

class Producer extends Thread {
    Data2 data;

    public Producer(Data2 data) {
        this.data = data;
    }

    public void run() {
        while (true) {
            while (true) {
                data.add();
            }
        }
    }
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
浪人 浪人
3年前
一篇文章弄懂Java多线程基础和Java内存模型
文章目录一、多线程的生命周期及五种基本状态二、Java多线程的创建及启动1.继承Thread类,重写该类的run()方法2.通过实现Runnable接口创建线程类3.通过Callable和Future接口创建线程三、Java内存模型概念四、内存间的交互操作五、volatile和synchronized的
Wesley13 Wesley13
3年前
Java面试系列
实现多线程的方式继承Thread类,重写run方法,调用start方法启动线程实现Runnable接口,重写run方法,调用start方法启动线程实现Callable接口,重写call方法,并用FutureTask包装,在newThread中传入FutureTask,然后调用start方
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这