JAVA学习日志(11-1-线程及多线程概述)
博客专区 > Almon 的博客 > 博客详情
JAVA学习日志(11-1-线程及多线程概述)
Almon 发表于1年前
JAVA学习日志(11-1-线程及多线程概述)
  • 发表于 1年前
  • 阅读 3
  • 收藏 1
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

进程:一个正在执行中的程序,每一个进程执行都有一个执行顺序

            该顺序就是一个执行路径/控制单元

线程:进程中的一个独立控制单元,控制着进程的执行

            一个进程中至少有一个线程

    eg.Java VM启动时会有一个进程java.exe

        该进程中至少有一个线程负责java程序的执行,而且这个线程运行的代码存在于

        main方法中,该线程成为主线程

        扩展:jvm启动不止一个线程,还有负责垃圾回收机制的线程

如何定义一个线程:Java-API-Thread类-继承Thread类

/* 
	1.定义类继承Thread
	2.复写Thread中的run方法
	3.调用线程的start方法:启动线程,调用run方法
    **CPU并不是同时进行线程,而是在不同线程之间切换进行
 */
class Demo extends Thread{
	public void run(){
		System.out.println("Demo_Run");
	}
}
class ThreadDemo{
	public static void main(String[] args){
		Demo d=new Demo();
		d.start();
	}
}

多线程运行即互相抢夺CPU的执行权,即多线程的运行具有随机性

为什么要覆盖run方法?

    Thread用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码,该储存

    功能就是run方法,即run用于储存线程要运行的代码

    覆写run()的目的在于储存自定义代码,让线程运行,

    **start()用于开启线程并执行run(),run()仅调用方法,创建线程,并未运行

线程的运行状态

    1.被创建

    2.运行    start()

    3.冻结:放弃执行资格    sleep(time) wait () notify()

    4.消亡    stop()

    **阻塞状态:等待cpu执行权,具备运行资格

获取线程对象及名称

    static Thread currentThread() 获取当前线程对象

    getName() 获取线程名称

    setName()/构造函数 设置线程名称

class Demo extends Thread{
	Demo(String name){
		super(name);
	}
	public void run(){
		for(int x=0;x<60;x++){
			System.out.println(Thread.currentThread()+this.getName()+"Demo_Run"+x);
		}
	}
}
class ThreadDemo{
	public static void main(String[] args){
		Demo d=new Demo("Mark_II");
		d.start();
		for(int x=0;x<60;x++){
			System.out.println("Demo"+x);
		}
	}
}

练习:卖票窗口

Ver 1.0

/* 
需求:简单的卖票程序
	多个窗口同时卖票
*/
class Ticket extends Thread{
	private static int tick=100; //用static 来共享总票数
	public void run(){
		while(true){
			if(tick>0){
				System.out.println(currentThread().getName()+"__"+"sale:"+tick--);
			}
		}
	}
}
class TicketDemo{
	public static void main(String[] args){
		Ticket t1=new Ticket();
		Ticket t2=new Ticket();
		Ticket t3=new Ticket();
		Ticket t4=new Ticket();
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

V 2.0 解决共享票数的问题

/* 
需求:简单的卖票程序
	多个窗口同时卖票
*/
class Ticket implements Runnable{//extends Thread{
	private int tick=100;
	public void run(){
		while(true){
			if(tick>0){
				System.out.println(Thread.currentThread().getName()+"__"+ "sale:"+tick--);
			}
		}
	}
}
class TicketDemo{
	public static void main(String[] args){
		Ticket t=new Ticket();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		Thread t3=new Thread(t);
		Thread t4=new Thread(t);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}
/* 创建线程的第二种方式:实现Runnable接口
	1.定义类实现Runnable接口
	2.覆盖Runnable接口中的run方法
		-将代码存放在该run方法中
	3.通过Thread类建立线程对象
	4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
		-自定义的run方法所属对象是Runnable接口的子类对象
		 所以要让线程去指定对象的run方法,就必须明确该run方法的所属对象
	5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法 */

实现方式和继承方式的区别

    实现方式:避免了单继承的局限性,建议使用。

                      线程代码存放在接口子类的run()

    继承方式:线程代码存放在Thread的子类run()中

线程的安全问题

/*
    通过分析,发现打印出0,-1,-2等错票
    多线程的运行出现了安全问题

*/

class Ticket implements Runnable{//extends Thread{
	private int tick=100;
	public void run(){
		while(true){
			if(tick>0){
				try{Thread.sleep(10);}catch(Exception e){}
				System.out.println(Thread.currentThread().getName()+"__"+ "sale:"+tick--);
			}
		}
	}
}
class TicketDemo{
	public static void main(String[] args){
		Ticket t=new Ticket();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		Thread t3=new Thread(t);
		Thread t4=new Thread(t);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

问题的原因:
   当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分
   还没有执行完,另一个线程参与进来执行,导致了共享数据的错误
解决办法:
    对多条操作共享数据的语句,只能让一个线程执行完,其他线程不可以参与执行

    Java对于多线程的安全问题提供了专业的解决方式——同步代码块

synchronized(对象){
    需要同步的代码
}


class Ticket implements Runnable{//extends Thread{
	private int tick=400;
	Object obj=new Object();
	public void run(){
		while(true){
			synchronized(obj){
				if(tick>0){
					try{Thread.sleep(10);}catch(Exception e){}
					System.out.println(Thread.currentThread().getName()+"__"+ "sale:"+tick--);
				}
			}
		}
	}
}

 

共有 人打赏支持
粉丝 2
博文 64
码字总数 44346
×
Almon
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: