Java进程(基础)
基本概念
1、进程:程序的执行过程
2、线程:一个进程可以有单个线程也就是我们说的单线程,还可以有多个线程也就是我们说的多线程,
线程
1、当一个类继承了Thread类就可以当成一个线程用
2、我们会重写run方法写上我们自己的业务逻辑
3、run Thread类实现了RUnnable接口,静态代理模式
创建一个线程为什么是start不是直接调用run方法,如果直接调用run方法并没有创建一个线程,而是串行执行,start方法中的start0方法创建一个线程是由本地方法,是由JVM调用的
当一个类他已经继承了其他类,但是我们还想让其作为线程使用的话就可以让其实现Runable接口
package threaduse;
public class Thread01 {
public static void main(String[] args) {
Cat cat = new Cat();
//没有start方法
//cat.start();
Thread thread = new Thread(cat);
thread.start();
}
}
class Cat implements Runnable
{
int cnt = 0;
@Override
public void run() {
while(true)
{
System.out.println("小狗汪汪叫hi " + (++ cnt) + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if(cnt == 10) break;
}
}
}
多个子线程案例
package threaduse;
public class Thread03 {
public static void main(String[] args) {
T1 t1 = new T1();
T2 t2 = new T2();
Thread thread = new Thread(t1);
Thread thread1 = new Thread(t2);
thread1.start();
thread.start();
}
}
class T1 implements Runnable
{
int cnt = 0;
@Override
public void run() {
while(true)
{
System.out.println("hello world " + (++cnt));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if(cnt == 10) break;
}
}
}
class T2 implements Runnable
{
int cnt = 0;
@Override
public void run() {
while(true)
{
System.out.println("hi " + (++cnt));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if(cnt == 10) break;
}
}
}
模拟售票
package ticket;
//使用多线程模拟三个窗口同时售票
public class SellTicket {
public static void main(String[] args) {
SellTicket01 sellTicket01 = new SellTicket01();
SellTicket01 sellTicket011 = new SellTicket01();
SellTicket01 sellTicket012 = new SellTicket01();
sellTicket012.start();
sellTicket011.start();
sellTicket01.start();
}
}
//使用继承Thread
class SellTicket01 extends Thread
{
private static int num = 100;
@Override
public void run() {
while(true)
{
if(num <= 0)
{
System.out.println("售票结束...");
break;
}
//休眠50ms
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
System.out.println("窗口 " + Thread.currentThread().getName() +
"售出一张票" + "剩余票数 = " + (-- num));
}
}
}
出现问题

票重复卖

这里先提出问题后续会解决啦
通知线程退出
package exit_;
public class Thread_Exit {
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.start();
//如果我们希望main线程去控制t线程的终止,必须可以修改loop->通知方式
//休眠10s
Thread.sleep(10 * 1000);
t.setLoop(false);
}
}
class T extends Thread
{
int cnt = 0;
//设置一个变量
private boolean loop = true;
@Override
public void run() {
while(loop)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("T还在运行" + (++ cnt));
}
}
public void setLoop(boolean loop) {
this.loop = loop;
}
}
线程中断
线程的常用方法
1、start会调用run方法并且会创建一个新线程而单独调用run方法并不会创建新线程
2、interrupt,中断线程一般用于结束正在休眠的线程
3、sleep线程的休眠
3、现成的优先级
MAX、MIN、NORM
package Method;
import sun.awt.windows.ThemeReader;
public class ThreadMethod01 {
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.setName("阿杜");
t.setPriority(Thread.MIN_PRIORITY);
t.start();
System.out.println(t.getName());
//主线程打印5个hi,然后就中断子线程的休眠
for(int i = 1; i <= 5; ++ i)
{
Thread.sleep(1000);
System.out.println("hi" + i);
}
t.interrupt();
}
}
//自定义的线程类
class T extends Thread
{
@Override
public void run() {
while(true)
{
for(int i = 0; i < 100; ++ i)
{
//Thread.currentThread().getName()获取当前线程的名称
System.out.println(Thread.currentThread().getName() + "吃包子~~~~~" + i);
}
try {
System.out.println(Thread.currentThread().getName() + "休眠中~~~~~");
Thread.sleep(5000);
} catch (InterruptedException e) {
//InterruptedException捕获到一个中断异常
System.out.println(Thread.currentThread().getName() + "被 interrupt了");
}
}
}
}
线程插队
yield:线程的礼让,让出cpu让其他线程先执行,让出的时间不确定,所以也不一定能成功让出
join:线程的插队,插队一旦成功,就一定会先执行完插队的进程
join方法调用的是对方的,也就是你想让插队的那个线程的
例题

package Method;
public class ThreadMethodExercise {
public static void main(String[] args) throws InterruptedException {
T3 t3 = new T3();
Thread thread = new Thread(t3);
for(int i = 1; i <= 10; ++ i)
{
System.out.println("hi " + i);
if(i == 5)
{
thread.start();
thread.join();
}
}
}
}
class T3 implements Runnable
{
@Override
public void run() {
for(int i = 1; i <= 10; ++ i)
{
System.out.println("hello " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}

用户线程和守护线程
用户线程:也叫工作线程,当线程的任务执行完或以通知的形式结束
守护线程:一般是为用户线程工作的,当所有用户线程结束守护线程自动结束
常见的守护线程:垃圾回收机制

package Method;
public class ThreadMethod03 {
public static void main(String[] args) throws InterruptedException {
MyDaemonThread myDaemonThread = new MyDaemonThread();
//我们希望当主线程结束后子线程能自动结束,我们需要将子线程设置为守护线程
myDaemonThread.setDaemon(true);
myDaemonThread.start();
for (int i = 1; i <= 10; ++i)
{
System.out.println("阿杜在辛苦的工作");
Thread.sleep(1000);
}
}
}
class MyDaemonThread extends Thread
{
@Override
public void run() {
for(;;)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("阿杜和阿范一直在聊天~~~~~");
}
}
}

线程的七大状态


线程同步
在多线程中,对一些敏感数据可能同一时刻只允许一个线程访问,为了保证数据的完整性,任何同一时刻我们都只让一个线程访问
synchronized
package syn;
class SellTicket03 implements Runnable
{
private static int num = 100;
private boolean loop = true;
public synchronized void sell(){
if(num <= 0)
{
System.out.println("售票结束。。。。");
loop = false;
return;
}
while(loop)
{
if(num <= 0)
{
System.out.println("售票结束...");
break;
}
//休眠50ms
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
System.out.println("窗口 " + Thread.currentThread().getName() +
"售出一张票" + "剩余票数 = " + (-- num));
}
}
@Override
public void run() {
sell();
}
}
//使用多线程模拟三个窗口同时售票
public class SellTicket {
public static void main(String[] args) {
SellTicket03 sellTicket03 = new SellTicket03();
SellTicket03 sellTicket031 = new SellTicket03();
Thread thread = new Thread(sellTicket03);
Thread thread1 = new Thread(sellTicket031);
thread.start();
thread1.start();
}
}
锁
互斥锁
上面的同步机制就是利用了锁,当多个线程运行时,他们先争夺锁,只有获得锁的线程才能执行方法,上面的售卖票利用的就是互斥锁
1、java引入互斥锁的概念是为了保证共享数据的完整性
2、互斥锁,用关键字synchronized修饰时表明该对象在任何同一时刻只能有一个线程访问
3、同步之后因为同一时刻只有一个线程在执行,所以效率自然会降低
4、如果锁加在方法上,如果方法是静态的,锁加在类上,如果方法是非静态的,锁加在当前对象(this)上或则其他对象上(并不是很理解呜呜呜~~~~~)
互斥锁想要起作用,多个线程锁的对象必须是同一个
死锁
双方都需要当前对方所拥有的锁资源
package syn;
public class DeadLock_ {
public static void main(String[] args) {
DeadLockDemo deadLockDemo = new DeadLockDemo(false);
DeadLockDemo deadLockDemo1 = new DeadLockDemo(true);
deadLockDemo1.start();
deadLockDemo.start();
}
}
class DeadLockDemo extends Thread
{
static Object o1 = new Object();
static Object o2 = new Object();
boolean flag;
public DeadLockDemo(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
if(flag)
{
synchronized (o1)
{
System.out.println(Thread.currentThread().getName() + "进入了o1");
synchronized (o2)
{
System.out.println(Thread.currentThread().getName() + "进入了o2");
}
}
}else{
synchronized (o2)
{
System.out.println(Thread.currentThread().getName() + "进入了o2");
synchronized (o1)
{
System.out.println(Thread.currentThread().getName() + "进入了o1");
}
}
}
}
}

释放锁
释放锁

不会释放锁

Java进程(基础)的更多相关文章
- Java多线程基础:进程和线程之由来
转载: Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够 ...
- Java并发基础:进程和线程之由来
转载自:http://www.cnblogs.com/dolphin0520/p/3910667.html 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程. ...
- 1、Java多线程基础:进程和线程之由来
Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...
- [转]Java多线程干货系列—(一)Java多线程基础
Java多线程干货系列—(一)Java多线程基础 字数7618 阅读1875 评论21 喜欢86 前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们 ...
- Java 多线程——基础知识
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- JAVA面试基础
JAVA相关基础知识1.面向对象的特征有哪些方面 ?1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂 ...
- 【重走Android之路】【Java面向对象基础(三)】面向对象思想
[重走Android之路][基础篇(三)][Java面向对象基础]面向对象思想 1 面向对象的WWH 1.1 What--什么是面向对象 首先,要理解“对象”.在Thinkin ...
- Java 并发基础
Java 并发基础 标签 : Java基础 线程简述 线程是进程的执行部分,用来完成一定的任务; 线程拥有自己的堆栈,程序计数器和自己的局部变量,但不拥有系统资源, 他与其他线程共享父进程的共享资源及 ...
- 我的学习目标(目前已初步学习完Java语言基础)
操作系统.尤其是内存/线程/进程方面 计算机网络协议,重点关注 TCP/UDP/HTTP. 数据结构与算法. 数据库 设计模式,熟练掌握常用的几种设计模式. Java语言基础.熟悉java语言基础,了 ...
- Java并发基础概念
Java并发基础概念 线程和进程 线程和进程都能实现并发,在java编程领域,线程是实现并发的主要方式 每个进程都有独立的运行环境,内存空间.进程的通信需要通过,pipline或者socket 线程共 ...
随机推荐
- vscode中react组件
通过使用这个插件我们可以很方便的进行组件/方法/文件的导入 本篇博客仅对插件进行介绍翻译,便于自己以后使用 常用片段列表 imr: 引入 React import React from 'react' ...
- ZEGO即构科技荣获36氪【WISE2020中国新经济之王最具影响力企业】
12月8-10日,36氪重磅新经济峰会WISE2020新经济之王大会将在北京举办.近日,2020新经济之王--中国最具影响力企业榜单陆续发布,全球云通讯服务商即构科技,凭借在企业服务领域硬核出色的技术 ...
- Stable Diffusion生成图片的参数查看与抹除方法
前几天分享了几张Stable Diffusion生成的艺术二维码,有同学反映不知道怎么查看图片的参数信息,还有的同学问怎么保护自己的图片生成参数不会泄露,这篇文章就来专门分享如何查看和抹除图片的参数. ...
- Typecho博客部署一言接口
开始部署 下载代码上传至你的网站目录,把解压出来的文件夹改名为hitokoto 然后访问https://域名及文件路径/hitokoto查看效果 示例:https://sunpma.com/other ...
- 趣图|代码重构前vs重构后
前言 很多程序员对自己写的代码平时很随心所欲,但当有一天让他维护他人的代码,他就会抓狂,很容易激发他体内重构的瘾.(大多数程序员审阅完别人代码后,先会忍不住吐槽一番,然后会忍不住想重构一把,) 在我看 ...
- 【pandas小技巧】--缺失值的列
在实际应用中,数据集中经常会存在缺失值,也就是某些数据项的值并未填充或者填充不完整.缺失值的存在可能会对后续的数据分析和建模产生影响,因此需要进行处理. pandas提供了多种方法来处理缺失值,例如删 ...
- quarkus数据库篇之三:单应用同时操作多个数据库
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 一个应用同时连接多个数据库进行操作,这是常见 ...
- 在Jupyter中使用AI写代码,如有神助,太惊艳了
昨晚看到一个可以在JupyterLab中使用的AI代码辅助工具jupyter-ai,它的交互确实非常棒,可以直接聊天,也可以就笔记中的代码提问,最出彩的是生成笔记功能,还是蛮惊艳的. 这里就极简介绍一 ...
- 快手商品详情API接口如何使用
使用快手开的API接口获取商品详情,可按照以下步骤进行: 1.注册账号并创建应用 注册开发者账号,并在账号后台中创建一个应用,获得AppKey和AppSecret等信息.这些信息是使用API接口访问快 ...
- Android 调试桥 (adb) 使用教程/示例
sidebar: auto Android 调试桥 (adb) Android 调试桥 (adb) 是一种功能多样的命令行工具,可让您与设备进行通信.adb 命令可用于执行各种设备操作,例如安装和调试 ...