-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
一、概述
进程:是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元 。
线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行,一个进程中至少有一个进程
特点:java虚拟机启动的时候会有一个进程java.exe,该进程中至少一个线程负责java程序的执行。而且这个线程运行的代码存在于main中,该线程称为主线程。
二、创建线程的方式
方式1、
1、定义类继承Thread
2、覆盖Thread中的run方法
|--将线程要运行的代码存放在该run方法中
3、通过Thread类建立线程对象
4、调用Thread类的start方法开启线程
方式2、
1.定义类实现Runnable接口2.覆盖Runnable接口中的run方法
|--将线程要运行的代码存放在该run方法中
3.通过Thread类建立线程对象
4.将Runnable接口的子类对象作为实际参数传给Thread类的构造参数
|--因为自定义的run方法所属的对象时Runnable接口的子类对象所以要让线程去执行指定对象的run方法
5.调用Thread类的start方法开启线程并调用Runnable接口子类的Run方法
实现方式和继承方式的区别:继承只能继承一次,实现避免了单继承的局限性,在定义线程时建议使用实现方式
两种创建方式的区别:
继承Thread:线程代码存放在Thread子类run方法中。
实现Runnable:线程代码存放在接口子类run方法中。
示例:
//需求:简单的卖票程序 class Ticket extends Thread{ private static int tick=20; public void run(){ while(true){ //while(tick>0) if(tick>0) //System.out.println(Thread.currentThread().getName()+"sale----"+tick--); System.out.println(Thread.currentThread().getName()+"sale----"+tick--); } } } public class ThreadDemo2 { public static void main(String[] args) { // TODO Auto-generated method stub Ticket t1=new Ticket(); Ticket t2=new Ticket(); Ticket t3=new Ticket(); t1.start(); t2.start(); t3.start(); } }
示例2:
class Ticket2b implements Runnable{ private int tick=20; public void run(){ while(true){ if(tick>0) System.out.println(Thread.currentThread().getName()+"sale----"+tick--); } } } public class ThreadDemo2b { public static void main(String[] args) { Ticket2b t=new Ticket2b();//不是线程因为不是Thread对象也不是他的子类对象 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(); } }
三、线程安全问题
1、导致线程安全问题的原因:
当多条语句在操作同一线程共享数据时,一个线程对语句只执行了一部分,还没执行完,另一个线程参与进来执行。导致错误
2、解决办法用到同步 synchronized
示例:银行有一个金库有两个储户分别存300,每次存100,存三次
class Bank{ private int num; public synchronized void add(int n){ // Object o=new Object(); // synchronized(o){ num=num+n; try{Thread.sleep(10);}/*有这个sleep就必须要抛或者try*/ catch(Exception e){} System.out.println(num); // } } } class Cus implements Runnable{ Bank b=new Bank(); public void run(){ for(int x=0;x<3;x++){ b.add(100);//因为这里掉用add方法所以上面add方法也是多线程运行代码 } } } public class BankDemo { public static void main(String[] args) { // TODO Auto-generated method stub Cus c=new Cus(); Thread t1=new Thread(c); Thread t2=new Thread(c); t1.start(); t2.start(); } }使用同步的前提:
1、必须要有两个或者两个以上的线程。
2、必须是多个线程使用同一个锁。
怎么发现线程安全问题?
1.明确哪些代码是多线程运行代码
2.明确共享数据
3.明确多线程运行代码中哪些语句是操作共享数据的
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------