应用程序的一个运行实例 包含程序所需要的资源的内存区域,是操作系统进行资源分配的单元
进程隔离了正在执行的不同程序
优点:进程间相互独立互补影响
进程中的一个执行单元(进程是程序的边界,要靠线程执行程序)线程执行方法 执行完毕释放线程是CPU分配时间片的单位 一个进程包含多个线程
且线程相互独立 共享当前进程的资源
单任务和多任务
2.
第一种方式:创建Thread子类
java.lang.Thread 描述线程的类 我们想实现多线程 必须继承 Thread类
1.创建一个Thread子类
2.重写run方法布置任务
3.创建Thread子类对象
4.调用Thread类中的Start方法 开启新线程 执行run方法
package MapList;
public class Thread1 extends Thread { //2.重写Thread类中的run方法 设置线程任务 public void run() { for(int i=0;i<20;i++) { System.out.println(“run:”+i); } }
}
package MapList;
public class MyThread { public static void main(String[]args) { Thread1 th=new Thread1(); th.start(); for(int i=0;i<20;i++) { System.out.println(“main”+i); }
}} 结果: main0 run:0 main1 main2 main3 main4 main5 run:1 main6 run:2 main7 run:3 main8 run:4 main9 main10 run:5 run:6 run:7 run:8 run:9 run:10 run:11 run:12 run:13 run:14 run:15 run:16 run:17 main11 main12 main13 main14 main15 main16 main17 main18 main19 run:18 run:19
第二种方式:实现runnable接口
java. lang.Runable 接口应该由那些打算通过某一线程执行其实例的类实现
类必须定义一个 无参数的方法(方法用来布置任务)
Thread 类方法和构造方法
Thread(Runnabe target) 分配新的Thread对象
Thread(Runnable Target,String name)分配新的Thread对象
1.创建一个Runnable接口实现类
2.在实现类中 重写Runnable接口的run方法
3.创建Runnable的实现类对象
4.创建Thread对象 构造方法中传递Runnable实现类对象
5.调用Thread的start方法
1.避免了单继承的局限性
2.增强了程序的拓展性,降低了耦合度(解耦)把继承关系变成组合关系
}
} 结果: runnable:0 runnable:1 runnable:2 runnable:3 runnable:4 runnable:5 runnable:6 runnable:7 runnable:8 runnable:9 runnable:10 runnable:11 runnable:12 runnable:13 runnable:14 runnable:15 runnable:16 runnable:17 runnable:18 main0 main1 main2 main3 run:0 runnable:19 run:1 main4 main5 run:2 run:3 run:4 run:5 run:6 run:7 run:8 run:9 run:10 run:11 run:12 main6 run:13 run:14 run:15 run:16 run:17 run:18 run:19 第三0 main7 main8 第三1 第三2 第三3 第三4 第三5 main9 第三6 main10 main11 第三7 main12 第三8 main13 第三9 main14 第三10 main15 第三11 第三12 第三13 第三14 main16 第三15 main17 第三16 main18 main19 第三17 第三18 第三19
``` java是抢占式执行 可以设置线程的优先级(执行概率会大大提高)
public class Demo1{
public static void main(String[]args){
System.out.println(“HelloWorld”)
}
}
分析:JVM执行main方法 main方法会进入栈内存,jvm会找操作系统开辟一条main方法通向cpu的执行路径,cup就可以通过这个执行路径来执行main方法,而这个路径取一个名字叫main(主)线程
setName getName sleep currentThread
public class Thread1 extends Thread {
//2.重写Thread类中的run方法 设置线程任务 public void run() { setName("线程1"); for(int i=0;i<20;i++) { System.out.println(getName()+i); } }} public static void main(String[]args) { Thread1 td=new Thread1(); //td.setName(“线程1”); td.start(); String name= td.getName();
System.out.println(name); }} 结果: Thread-0 线程10 线程11 线程12 线程13 线程14 线程15 线程16 线程17 线程18 线程19 线程110 线程111 线程112 线程113 线程114 线程115 线程116 线程117 线程118 线程119
public static void main(String[]args) throws InterruptedException { // Thread1 td=new Thread1(); // td.setName(“线程1”); // td.start(); // String name= td.getName(); // // System.out.println(name); for(int i=0;i<20;i++) {
Thread.sleep(1000);//睡眠毫秒 System.out.println(i); } }} 结果: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
public static void main(String[]args) throws InterruptedException { // Thread1 td=new Thread1(); // td.setName(“线程1”); // td.start(); // String name= td.getName(); // // System.out.println(name); for(int i=0;i<20;i++) { //Thread.sleep(1000); System.out.println(i); } System.out.println(Thread.currentThread()); 结果: Thread[main,5,main] System.out.println(Thread.currentThread().getName()); 结果: main System.out.println(Thread.currentThread().currentThread().currentThread()); //链式编程 结果: Thread[main,5,main]
}} 结果: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
```package MapList;
public class RunnableImpl1 implements Runnable{ //总票数 private int ticket=100; //设置线程任务买票 public void run() { while(true){ //使用无线循环让买票操作重复执行 if(ticket>0) { try { Thread.sleep(10);//模拟出票的过程
}catch(Exception e) { } System.out.println(Thread.currentThread().getName()+"正在买---->"+ticket+"张票"); ticket--; } } }} public static void main(String[]args) { Runnable r=new RunnableImpl1(); Thread td=new Thread®; td.start(); Thread td1=new Thread®; td1.start();
}} 结果: Thread-1正在买---->100张票 Thread-0正在买---->100张票 Thread-0正在买---->98张票 Thread-1正在买---->98张票 Thread-1正在买---->96张票 Thread-0正在买---->96张票 Thread-1正在买---->94张票 Thread-0正在买---->94张票 Thread-0正在买---->92张票 Thread-1正在买---->92张票 Thread-1正在买---->90张票 Thread-0正在买---->90张票 Thread-0正在买---->88张票 Thread-1正在买---->88张票 Thread-0正在买---->86张票 Thread-1正在买---->86张票 Thread-0正在买---->84张票 Thread-1正在买---->84张票 Thread-0正在买---->82张票 Thread-1正在买---->82张票 Thread-0正在买---->80张票 Thread-1正在买---->80张票 Thread-0正在买---->78张票 Thread-1正在买---->78张票 Thread-1正在买---->76张票 Thread-0正在买---->76张票 Thread-0正在买---->74张票 Thread-1正在买---->74张票 Thread-1正在买---->72张票 Thread-0正在买---->72张票 Thread-1正在买---->70张票 Thread-0正在买---->70张票 Thread-1正在买---->68张票 Thread-0正在买---->68张票 Thread-0正在买---->66张票 Thread-1正在买---->66张票 Thread-1正在买---->64张票 Thread-0正在买---->64张票 Thread-0正在买---->62张票 Thread-1正在买---->62张票 Thread-1正在买---->60张票 Thread-0正在买---->60张票 Thread-0正在买---->58张票 Thread-1正在买---->58张票 Thread-0正在买---->56张票 Thread-1正在买---->56张票 Thread-0正在买---->54张票 Thread-1正在买---->54张票 Thread-1正在买---->52张票 Thread-0正在买---->52张票 Thread-0正在买---->50张票 Thread-1正在买---->50张票 Thread-0正在买---->48张票 Thread-1正在买---->48张票 Thread-0正在买---->46张票 Thread-1正在买---->46张票 Thread-1正在买---->44张票 Thread-0正在买---->44张票 Thread-0正在买---->42张票 Thread-1正在买---->42张票 Thread-0正在买---->40张票 Thread-1正在买---->40张票 Thread-0正在买---->38张票 Thread-1正在买---->38张票 Thread-1正在买---->36张票 Thread-0正在买---->36张票 Thread-1正在买---->34张票 Thread-0正在买---->34张票 Thread-1正在买---->32张票 Thread-0正在买---->32张票 Thread-1正在买---->30张票 Thread-0正在买---->30张票 Thread-0正在买---->28张票 Thread-1正在买---->28张票 Thread-1正在买---->26张票 Thread-0正在买---->26张票 Thread-1正在买---->24张票 Thread-0正在买---->24张票 Thread-1正在买---->22张票 Thread-0正在买---->22张票 Thread-1正在买---->20张票 Thread-0正在买---->20张票 Thread-1正在买---->18张票 Thread-0正在买---->18张票 Thread-1正在买---->16张票 Thread-0正在买---->16张票 Thread-0正在买---->14张票 Thread-1正在买---->14张票 Thread-0正在买---->12张票 Thread-1正在买---->12张票 Thread-0正在买---->10张票 Thread-1正在买---->10张票 Thread-0正在买---->8张票 Thread-1正在买---->8张票 Thread-0正在买---->6张票 Thread-1正在买---->6张票 Thread-0正在买---->4张票 Thread-1正在买---->4张票 Thread-0正在买---->2张票 Thread-1正在买---->2张票 Thread-0正在买---->0张票 注意: 两个人同时去买票线程不安全 t0进来了线程抢到了cup的执行权 进入到run方法 执行到if之后 就失去了cpu执行权( 睡了) t1也进来了 (睡了)出现了一样的数据在减减之前同时执行到System.out.println()了。 (线程不安全)
``` Synchronized(锁对象){
可能会出现线程安全的问题的代码
}
package MapList;
public class RunnableImpl1 implements Runnable{ //总票数 private int ticket=100; Object obj=new Object(); //设置线程任务买票 public void run() { while(true){ //使用无线循环让买票操作重复执行 //锁对象 任意 synchronized(obj) { if(ticket>0) { try { Thread.sleep(10);//模拟出票的过程
}catch(Exception e) { } System.out.println(Thread.currentThread().getName()+"正在买---->"+ticket+"张票"); ticket--; } } } }}
public static void main(String[]args) { Runnable r=new RunnableImpl1(); Thread td=new Thread®; td.start(); Thread td1=new Thread®; td1.start(); Thread td2=new Thread®; td1.start();
}}
结果: Thread-0正在买---->100张票 Thread-0正在买---->99张票 Thread-0正在买---->98张票 Thread-0正在买---->97张票 Thread-0正在买---->96张票 Thread-0正在买---->95张票 Thread-1正在买---->94张票 Thread-1正在买---->93张票 Thread-1正在买---->92张票 Thread-1正在买---->91张票 Thread-1正在买---->90张票 Thread-1正在买---->89张票 Thread-1正在买---->88张票 Thread-1正在买---->87张票 Thread-1正在买---->86张票 Thread-1正在买---->85张票 Thread-1正在买---->84张票 Thread-1正在买---->83张票 Thread-1正在买---->82张票 Thread-1正在买---->81张票 Thread-1正在买---->80张票 Thread-1正在买---->79张票 Thread-1正在买---->78张票 Thread-1正在买---->77张票 Thread-1正在买---->76张票 Thread-1正在买---->75张票 Thread-1正在买---->74张票 Thread-1正在买---->73张票 Thread-1正在买---->72张票 Thread-1正在买---->71张票 Thread-1正在买---->70张票 Thread-1正在买---->69张票 Thread-1正在买---->68张票 Thread-1正在买---->67张票 Thread-1正在买---->66张票 Thread-1正在买---->65张票 Thread-1正在买---->64张票 Thread-1正在买---->63张票 Thread-1正在买---->62张票 Thread-1正在买---->61张票 Thread-1正在买---->60张票 Thread-1正在买---->59张票 Thread-1正在买---->58张票 Thread-1正在买---->57张票 Thread-1正在买---->56张票 Thread-1正在买---->55张票 Thread-1正在买---->54张票 Thread-1正在买---->53张票 Thread-1正在买---->52张票 Thread-1正在买---->51张票 Thread-1正在买---->50张票 Thread-1正在买---->49张票 Thread-1正在买---->48张票 Thread-1正在买---->47张票 Thread-1正在买---->46张票 Thread-1正在买---->45张票 Thread-1正在买---->44张票 Thread-1正在买---->43张票 Thread-1正在买---->42张票 Thread-1正在买---->41张票 Thread-1正在买---->40张票 Thread-1正在买---->39张票 Thread-1正在买---->38张票 Thread-1正在买---->37张票 Thread-1正在买---->36张票 Thread-1正在买---->35张票 Thread-1正在买---->34张票 Thread-1正在买---->33张票 Thread-1正在买---->32张票 Thread-1正在买---->31张票 Thread-1正在买---->30张票 Thread-1正在买---->29张票 Thread-1正在买---->28张票 Thread-1正在买---->27张票 Thread-1正在买---->26张票 Thread-1正在买---->25张票 Thread-1正在买---->24张票 Thread-1正在买---->23张票 Thread-1正在买---->22张票 Thread-1正在买---->21张票 Thread-1正在买---->20张票 Thread-1正在买---->19张票 Thread-1正在买---->18张票 Thread-1正在买---->17张票 Thread-1正在买---->16张票 Thread-1正在买---->15张票 Thread-1正在买---->14张票 Thread-1正在买---->13张票 Thread-1正在买---->12张票 Thread-1正在买---->11张票 Thread-1正在买---->10张票 Thread-1正在买---->9张票 Thread-1正在买---->8张票 Thread-1正在买---->7张票 Thread-1正在买---->6张票 Thread-1正在买---->5张票 Thread-1正在买---->4张票 Thread-1正在买---->3张票 Thread-1正在买---->2张票 Thread-1正在买---->1张票
```注意事项:
1.通过代码块中的锁对象 可以使用任意的对象
2.但是必须保证多个线程使用的锁对象是一个
3.锁对象的作用:
把同步代码块锁住 只让一个线程在同步代码块执行
步骤:1.把访问了共享数据的代码抽取出来放到一个方法中
2.把方法添加关键字synchronized
package MapList;
public class RunnableImpl1 implements Runnable{ //总票数 private int ticket=10; Object obj=new Object(); //设置线程任务买票 public void run() { while(true){ //使用无线循环让买票操作重复执行 //锁对象 任意 //synchronized(obj) { extracted();
} //} } //锁的是this private synchronized void extracted() { synchronized(this){ if(ticket>0) { try { Thread.sleep(10);//模拟出票的过程 }catch(Exception e) { } System.out.println(Thread.currentThread().getName()+"正在买---->"+ticket+"张票"); ticket--; } } }}
public static void main(String[]args) { Runnable r=new RunnableImpl1(); Thread td=new Thread(r); td.start(); Thread td1=new Thread(r); td1.start(); Thread td2=new Thread(r); td1.start(); }}
this是创建对象之后产生的 静态方法属于类优先于this所以静态没有this
package MapList;
public class RunnableImpl1 implements Runnable{ //总票数 private static int ticket=10; Object obj=new Object(); //设置线程任务买票 public void run() { while(true){ //使用无线循环让买票操作重复执行 //锁对象 任意 //synchronized(obj) { extracted1();
} //} } private static synchronized void extracted1() { synchronized(RunnableImpl1.class){ if(ticket>0) { try { Thread.sleep(10);//模拟出票的过程 }catch(Exception e) { } System.out.println(Thread.currentThread().getName()+"正在买---->"+ticket+"张票"); ticket--; } } }}
public static void main(String[]args) { Runnable r=new RunnableImpl1(); Thread td=new Thread(r); td.start(); Thread td1=new Thread(r); td1.start(); Thread td2=new Thread(r); td1.start(); }}
this是创建对象之后产生的 静态方法属于类优先于this所以静态没有thispackage MapList;
public class RunnableImpl1 implements Runnable{ //总票数 private static int ticket=10; Object obj=new Object(); //设置线程任务买票 public void run() { while(true){ //使用无线循环让买票操作重复执行 //锁对象 任意 //synchronized(obj) { extracted1();
} //} } private static synchronized void extracted1() { synchronized(RunnableImpl1.class){ if(ticket>0) { try { Thread.sleep(10);//模拟出票的过程 }catch(Exception e) { } System.out.println(Thread.currentThread().getName()+"正在买---->"+ticket+"张票"); ticket--; } } }}
public static void main(String[]args) { Runnable r=new RunnableImpl1(); Thread td=new Thread(r); td.start(); Thread td1=new Thread(r); td1.start(); Thread td2=new Thread(r); td1.start(); }}