线程
程序是静态的,程序是指指令和数据的有序合集;
线程是动态的,系统资源的分配;
一个进程会有若干个线程,一个进程至少有一个线程;线程是CPU调度和执行的单位;
线程就是独立执行的路径;
对同一份资源操作的时候,会存在资源抢夺的问题,需要加入并发控制;
线程会带来额外的开销,如:CPU调度时间;
每一个线程在自己的工作内存交互,内存控制不当会造成数据不一致;
1、创建线程:
a、写一个线程的方法,继承Thread类,并重写run方法;
b、并将要执行方法体写在里面;
c、在创建线程对象启用start(); 方法;
public class Test extends Thread { @Override public void run() { for (int i = 1; i < 11; i++) { System.out.println("好"+i); } } public static void main(String[] args) { Test Thread1 = new Test(); Thread1.start(); } }
run方法主线程只执行一条路径; 而start方法可以同时执行多条路径,交替执行;
线程不一定立即执行,由CPU调度;
2、通过实现Runable接口,重写run()方法,执行线程需要将它代理给新的线程,最后在启用start方法;
public class Threadtest implements Runnable{ @Override public void run() { for (int i = 1; i < 11; i++) { System.out.println("好"+i); } } public static void main(String[] args) { Threadtest n1 = new Threadtest(); new Thread(n1).start(); //创建Runable的实现对象,在一个线程对象,并将它代理该对象,启用start方法; for (int i = 1; i < 11; i++) { System.out.println("学习"+i); } } }
继承Thread类和实现Runable接口两种方法,第一步都是需要重写Run方法,但是实现的时候,Runable接口需要new Thread进行代理来实现,最后启动start方法;
//火车票抢票模拟; public class Thread03 implements Runnable { private int ticknum=20; //票数 @Override public void run() { while (true){ if(ticknum<1) { break; } try { Thread.sleep(200); //用于线程的睡眠,以免一个线程获得所以的票数 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"拿到了第"+ticknum--+"张票"); //用Thread的getname得到获得票的姓名; } } public static void main(String[] args) { Thread03 n1=new Thread03(); new Thread(n1,"小红").start(); new Thread(n1,"小李").start(); new Thread(n1,"黄牛").start(); } }
注意:多个线程同时操控一个资源的时候,线程不安全甚至会引发线程的紊乱,所以需要解决并发问题;