您的位置 首页 java

Java中——线程详解

1.什么是进程?

一个进程对应一个应用程序。 例如:在windows操作系统启动Word就表示启动了一个进程。在 Java 的开发环境下启动 JVM ,就表示启动了一一个进程。现代的计算机都是支持多进程的,在同一个操作系统中,可以同时启动多个进程。。

2.多进程有什么作用?

单进程计算机只能做一件事情。 。

玩电脑,一边玩游戏 (游戏进程)边听音乐 (音乐进程),

对于单核计算机来讲,在同一个时间点上.游戏进称和音乐进程是同时在运行吗?不是。因为计算机的CPU只能在某个时间点上做一件事,由于计算机将在“游戏进程”和“音乐进程”之间频繁的切换执行,切换速度极高,人类感觉游戏和音乐在同时进行, 是为了提高cpu的使用率

.2.2、 线程的创建和启动

Java虚拟机的 主线程 入口是main方法,用户可以自已创建线程,创建方式有两种:

  1. 继承 Thead类
  2. 实现Runnable接口 (推荐使用Runnable接口)。

java程序的运行原理

java命令会启动Java虚拟机,启动JVM,等于启动了一个应用程序,表示启动了一个进程

该进程会自动创建一个主线程,然后主线程去调用某个类的main方法,所以main方法运行在主线程中。

3什么是线程?

线程是一个进程中的执行场景,一个进程可以启动多个线程

多线程 有什么作用?

多线程是不是为了提高执行速度, 而是为了提高应用程序的使用率。

实例代码1

public class ThreadTest01 {
public static void main(String[] args) {
//创建线程
Thread t=new Processor();
//启动
t.start();//这段代码执行瞬间结束,告诉JVM再分配一个新的栈给t线程
 //run不需要我们手动调用,系统线程启动之后会自动调用
//t.run();这两种方法有本质区别,这只是普通方法调用,这样程序只有一个线程,run方法结束之后,下面程序才会继续执行
//这段代码在主线程中运行
for(int i=0;i<10;i++){
 System .out.println("main---->"+i);
}
//有了多线程之后,main方法结束只是主线程栈中没有方法栈帧了。
//但是其他线程或者而其他栈中还有栈帧,所以main方法结束,程序还可能继续运行
}
}
//创建线程的第一种方式
class Processor extends Thread{
public void run(){
for(int i=0;i<30;i++){
System.out.println("run------>"+i);
}
}
}
 

实例代码2

public class ThreadTest02 {
public static void main(String[] args) {
//创建线程
Processor1 p=new Processor1();
Thread t1=new Thread(p);
//启动线程
t1.start();
for(int i=0;i<30;i++){
System.out.println("main---->"+i);
}
}
}
//java实现线程的第二种方式
class Processor1 implements Runnable{
public void run(){
for(int i=0;i<30;i++){
System.out.println("run-----)"+i);
}
}
}
 

4.线程的声明周期

线程 的生命周期分为五个状态:新建 、就绪、运行、阻塞、消亡

新建:采用new语句创建完成

就绪:执行start后

运行:占用cpu时间片

阻塞:执行了wait语句,执行了sleep语句和等待某个对象锁

终止:执行了run()方法

5.线程的调度与控制

通常我们的计算机只有一个CPU.CPU在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。在单CPU的机器上线程不是并行运行的,只有在多个CPU上线程才可以并行运行。Java 虚拟机要负责钱程的调度,取得CPU的使用权,目前有两种调度模型:分时调度模型和抢占式调度模型,Java使用抢占式调度模型, 分时调度模型 :所有线程轮流使用CPU的使用权。平均分配每个线程占用CPU的时间片。 抢占式调度模型 :优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多一些

实例代码

/*
 * 关于线程的优先级
 * */public class  Thread Test03 {
public static void main(String[] args) {
//如何获取当前对象
Thread t=Thread.currentThread();//t保存的内存地址指向的线程是“主线程对象”
//获取线程的名字
System.out.println(t.getName()); //main

Thread t1=new Thread(new Processor2());

//给线程取名字
t1.setName("t1");
t1.start();
Thread t2=new Thread(new Processor2());
t2.setName("t2");
t2.start();

}
}
class Processor2 implements Runnable{
public void run() {
// TODO Auto-generated method stub
Thread t=Thread.currentThread();
System.out.println(t.getName());
}

}
 

6.同步编程与异步编程

t1和t2

异步编程模型 : t1线程执行t1的,t2线程执行t2的,两个线程之向谁也不等谁。

同步编程模型 : t1线程和t2线程执行,当t2线程 必须等t2线程执行结束之后,t1线程才能执行,这是同步编程模型。

1.为什么使用线程同步

为了数据的安全,尽管应用程序的使用率降低,但是为了保证数据是安全的,必须加入线程同步机制,线程同步机制,使程序变成了单线程

2.什么条件下 要使用线程同步

第一:必须是多线程环境

第二:多线程环境共享同一个数据

第三:共享的数据涉及到修改操作。

不使用同步实现银行账户取款(数据错误)

public class ThreadTest04 {
public static void main(String[] args) {
//创建一个公共账户
Account act=new Account("actno-001",5000.0);
//创建线程对同一个账户取款
Processor3 p=new Processor3(act);
Thread t1=new Thread(p);
Thread t2=new Thread(p);
t1.start();
t2.start();
}
}
//取款线程
class Processor3 implements Runnable{
//账户
Account act;
 Processor3(Account act){
 this.act=act;
 }
public void run() {
// TODO Auto-generated method stub
act.withdraw(1000.0);
System.out.println("取款1000成功,余额:"+act.getBalance());
}

}
class Account{
private String actno;
private double balance;
public Account(){}
public Account(String actno,double balance){
this.actno=actno;
this.balance=balance;

}
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//对外取款方法
public void withdraw(double money){
double after=balance-money;
//更新
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.setBalance(after);
}

}
 

使用线程同步(安全机制)

原理: t1线程和t2线程

t1线程执行到此处,遇到了synchronized关键字,就会去找this的对象锁,

如果找到this对象锁,则进入同步语句块中执行程序。当同步语句块中的代码执行结束之后t1线程归还this的对象锁.

在t1线程执行同步语句块的过程中,如果t2线程也过来执行以下代码,也遇到synchronizd关健字,所以也去找this的对象镜,但是该对象锁被t1线程持有,只能在这等待this对象的归还。|

public class ThreadTest05 {
public static void main(String[] args) {
//创建一个公共账户
Account1 act=new Account1("actno-001",5000.0);
//创建线程对同一个账户取款
//Processor4 p=new Processor4(act);
Processor4 p=new Processor4(act);
Thread t1=new Thread(p);
Thread t2=new Thread(p);
t1.start();
t2.start();
}
}
//取款线程
class Processor4 implements Runnable{
//账户
Account1 act;
Processor4(Account1 act){
this.act=act;
}
public void run() {
// TODO Auto-generated method stub
act.withdraw(1000.0);
System.out.println("取款1000成功,余额:"+act.getBalance());
}
}
class Account1{
private String actno;
private double balance;
public Account1(){}
public Account1(String actno,double balance){
this.actno=actno;
this.balance=balance;
}
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//对外取款方法
public void withdraw(double money){
//把需要同步的代码,放到同步语句块中
synchronized(this){
double after=balance-money;
//更新
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.setBalance(after);
}
}
}
 

文章来源:智云一二三科技

文章标题:Java中——线程详解

文章地址:https://www.zhihuclub.com/177954.shtml

关于作者: 智云科技

热门文章

网站地图