进程和线程
一个进程(.exe)包含多个线程
线程占的是进程内存的资源
为什么?就好像QQ 可以一边和别人视频,一边和别人打字聊天
有图有真相
实例
编写一个Java程序实现多线程,在线程中输出线程的名字,1000毫秒输出一次,共输出10次
-
实现多线程的方式
1、 继承Thread类
2、 实现Runnable接口 -
输出线程的名字? 考察继承(super)
具体代码如下(Runnable实现)
public class App02 implements Runnable{
Thread t;
public App02(){
/*
* this代表的是App02,而App02实现的是Runnable接口
* 所以可以正确传参
* */
t= new Thread(this,"实现线程一");
t.start();
}
public static void main(String[] args) {
new App02();
}
public void run() {
for (int i=0;i<10;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) { //被中途打断的情况
e.printStackTrace();
}
//getName()从父类继承而来的
System.out.println(Thread.currentThread().getName());
}
}
}
继承Thread实现
public class App01 {
public static void main(String[] args) {
MyThread myThread = new MyThread("继承线程一");
myThread.start();
// 线程具有随机性,有时候先启动线程一,有时候先启动线程二
// MyThread myThread2 = new MyThread("线程二");
// myThread2.start();
}
}
class MyThread extends Thread{
public MyThread(String threadName){
/*赋值
* 构造方法赋值
* setXXX赋值
* */
//super父类的threadName,按住Ctrl点击supper即可到达
super(threadName);
}
@Override
public void run() {
//super.run();
//System.out.println(Thread.currentThread().getName());
for (int i=0;i<10;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) { //被中途打断的情况
e.printStackTrace();
}
System.out.println(getName()); //getName()从父类继承而来的
}
}
}
同步和异步
当个线程访问同一个资源的时候,要注意线程同步的问题,如果不同步容易造成数据没及时修改,然后就被另一个线程访问,得到的数据还是上一次的数据,造成数据错误的情况。所以需要排队,等前面一个人处理完数据之后,后一个人才能去访问它。
当应用程序在对象上调用了一个需要很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步线程,在很多情况下,采用异步途径往往更有效率。
线程协作:需要建立在线程同步的情况下
下面举个例子
生产和销售同时发生(设置断点可以调试查看)
防止生产和销售同时发生(即实现同步):synchronized
App03(用于启动线程)
public class App03 {
public static void main(String[] args) {
Product product = new Product();
Thread producer = new Thread(new Producer(product));
producer.start();
Thread seller = new Thread(new Seller(product));
seller.start();
}
}
Producer(生产者)
public class Producer implements Runnable{
Product product;
public Producer(Product product){
this.product=product;
}
public void run() {
for (int i=0;i<10;i++){
product.produce();
}
}
}
Seller(销售者)
public class Seller implements Runnable {
//关联
//roduct p = new Product();
Product product;
public Seller(Product product){
this.product=product;
}
public void run() {
for (int i=0;i<10;i++){
product.sell();
}
}
}
Product(产品)
/*
* 同一个对象只有一把锁
* synchronized:加锁,实例方法,同一时刻,同一对象(product),方法只有一个被调用
* 被系统选中才能运行
* */
public class Product {
public synchronized void produce(){
System.out.println("生产商品");
}
public synchronized void sell(){
System.out.println("销售商品");
}
}
Product的方法未添加 synchronized 时,生产和销售同时
运行(会出现先销售再生产的情况,显然不符合实际)
Product的方法 添加 synchronized 时,生产和销售不能同时
运行
如何实现线程使用的是同一个对象?