线程
1.概念与原理
1.1线程和进程的概念
现在的操作系统是多任务操作系统,而多线程是实现多任务的一种方式
进程:是指内存中运行的应用程序,有自己独立的内存空间,可以独立的运行,进程彼此之间互不干扰,一个进程可以包含多个线程
线程:是进程中的一个执行流程,一个进程包含多个线程,线程与线程之间共享该进程的资源
进程和线程都是实现多任务的技术,但是进程是资源分配的基本单位,线程是程序执行的基本单位
1.2 java中的线程
在Java中 使用java.lang.Thread类或者Java.lang.Runnable接口编写代码来定义、实例化和启动一个新线程。
一个Thread类实例只是一个对象,和其它对象一样,具有变量和方法,生死于堆上。
2. 线程的创建与启动
2.1 继承Threat类
//使用一个类继承Threat类,然后重写run方法
//多线程抢占式运行
class MyThread extends Thread{@Overridepublic void run() {for (int i=0;i<100;i++)System.out.println("线程1:"+i);}
}
class MyThread1 extends Thread{private String threadName;@Overridepublic void run() {for (int i=0;i<100;i++)System.out.println("线程2:"+i);}
}public class A_Thread {public static void main(String[] args) {MyThread myThread = new MyThread();myThread.start();MyThread1 myThread1 = new MyThread1();myThread1.start();for (int i=0;i<100;i++)System.out.println("主线程:"+i);}
}
2.2 实现Runnable接口
class Methread implements Runnable{@Overridepublic void run() {for (int i=0;i<100;i++)System.out.println("线程1:"+i);}
}
class Methread1 implements Runnable{@Overridepublic void run() {for (int i=0;i<100;i++)System.out.println("线程2:"+i);}
}
public class B_Runnable {public static void main(String[] args) {Methread mt = new Methread();Thread thread = new Thread(mt);thread.start();Thread thread1 = new Thread(new Methread1());thread1.start();for (int i=0;i<100;i++)System.out.println("主线程:"+i);}
}
2.3 线程的方法
构造方法:
Thread | 创建新的Thread对象 |
---|---|
Thread(Runnable target) | 传入一个实现Runnable接口的实例作为参数,创建Thread对象 |
Thread(Runnable target,String name) | 创建Thread对象并起名字 |
线程下面的方法
int | getPriority();返回线程优先级 |
---|---|
void | setPriority(int newPriority);更改线程优先级 |
class MyThread1 implements Runnable{@Overridepublic void run() {for (int i=0;i<=100;i++)System.out.println(Thread.currentThread().getName()+":"+i);}
}
class Mythread2 implements Runnable{@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}
}public class A_Priority {public static void main(String[] args) {Thread thread1 = new Thread(new MyThread1(), "线程一");Thread thread2 = new Thread(new Mythread2(), "二号");thread1.setPriority(7);//虽然thread1的优先级比较高,但执行的时候还是抢占式,并不会因为优先级高就先执行//结果不可预期thread1.start();thread2.start();}
}
/*二号:41
二号:42
线程一:87
二号:43
二号:44
二号:45
线程一:88
线程一:89*/
3.线程同步和锁
为什么要线程同步:当多个线程同时请求一个数据的时候,可能会导致数据不准确的情况
class SaleTicket implements Runnable{@Overridepublic void run() {int count=100;while(true){if (count<0)break;System.out.println(Thread.currentThread().getName()+"剩余票数:"+count);count--;}}
}public class A_NotTongBu {public static void main(String[] args) {SaleTicket saleTicket = new SaleTicket();new Thread(saleTicket, "线程1").start();new Thread(saleTicket, "线程2").start();}
}
/*线程2剩余票数:36
线程2剩余票数:35
线程1剩余票数:98
线程1剩余票数:97
线程1剩余票数:96
线程1剩余票数:95
线程2剩余票数:34
线程2剩余票数:33
*/
对于这种情况我们可以在方法声明的时候加上一锁,可以使用synchronized关键字,也可以加在循环的时候,这样就可以防止多个线程在访问同一个资源的时候,避免出现线程不安全的情况。
4.死锁
死锁是线程的一种状态,当两个对象需要访问彼此所持有的资源,但是又不肯释放自身所持有的资源时,两个线程僵持住,就是死锁。
5.Object类下面与线程有关的方法
void wait() | 让当前线程等待,直到另一个线程调用当前对象的notify |
---|---|
void notify() | 唤醒线程池中等待的线程 |
void notifyAll() | 唤醒所有等待中的所有线程 |
6.线程的生命周期
线程的创建与启动 start
可以运行的状态 抢占 等待
执行状态 抢占 执行
阻塞 wait sleep 锁
消亡 destroy
7.生产者消费者模式
生产者,消费者,商品三者要遵循一定的规律,
当有商品时消费者可以消费,
当没有商品时消费者不能消费,生产者需要生产,
当商品栏满的时候生产者停止生产,消费者可以消费
class Goods{private String name;private String id;private boolean isProduct;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getId() {return id;}public void setId(String id) {this.id = id;}public boolean isProduct() {return isProduct;}public void setProduct(boolean product) {isProduct = product;}public Goods(String name, String id, boolean isProduct) {this.name = name;this.id = id;this.isProduct = isProduct;}
}class Customer implements Runnable{private Goods goods;public Customer(Goods goods) {this.goods = goods;}@Overridepublic void run() {while(true){synchronized (goods){if (!goods.isProduct()){//不需要生产System.out.println("消费者购买了:"+goods.getName()+",价格为:"+goods.getId());goods.setProduct(true);goods.notify();}else{try {goods.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}
}class Productor implements Runnable{private Goods goods;public Productor(Goods goods) {this.goods = goods;}@Overridepublic void run() {int count=0;int num=0;while (num<100){num++;synchronized (goods){if (goods.isProduct()){if (count%2==0){goods.setName("比亚迪元");goods.setId("10");goods.setProduct(false);count++;System.out.println("制造了第"+num+"辆:"+goods.getName()+",价格为:"+goods.getId());}else{goods.setName("比亚迪唐");goods.setId("30");goods.setProduct(false);count++;System.out.println("制造了第"+num+"辆:"+goods.getName()+",价格为:"+goods.getId());}goods.notify();}else{try {goods.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}
}public class Test1 {public static void main(String[] args) {Goods goods = new Goods("MINI", "4.4", true);Customer customer = new Customer(goods);Productor productor = new Productor(goods);new Thread(customer).start();new Thread(productor).start();}
}