多线程 (基础)

线程的基础内容

程序、进程、线程

  • 一个进程中至少有一个线程
    各个应用程序之间去抢占CPU资源,在同一个时间点上,CPU只能处理一个程序,看上去像是同时在进行,其实是CPU在快速的切换,进程抢占到CPU资源后,各个线程就去抢,那个线程先抢到就执行那个线程,(所以每一次执行的顺序都不一样)
  • 在java虚拟机上启动的时候会有一个进程java.exe,该进程中至少有一个线程,在负责java程序的执行。而且这个线程运行的代码在main方法中,该线程为主线程
  • 但是线程结束,进程未必结束,但进程结束,线程一定结束,线程是进程中的一部分

线程的创建和启动

  • 在java中负责线程的这个功能的是java.lang.Thread这个类
  • 可以通过new Thread(创建Thread的实例)来创建新的线程
  • 每个都是通过某个特定Thread对象所对应的run()方法完成其操作,run()方法称为线程体。
  • 可以通过调用Thread类的start()方法来启动一个线程。
  • 继承Thread类 ,重写run方法,创建对象,调用start()方法,启动线程。

代码如下:

public class A extends Thread{
	@Override
	public void run() {
		System.out.println("我是A");
	}
	public static void main(String[] args) {
		A a=new A();
		Thread t=new Thread(a);
		a.start();
	}
}
    • 创建线程的第二个方式:
  • 实现Runnable接口,重写run方法,创建对象,启动线程。

代码如下:

public class B implements Runnable{
	@Override
	public void run() {
		System.out.println("我是B");
	}
	public static void main(String[] args) {
		B b=new B();
		Thread t=new Thread(b);
//也可以这样  Thread t=new Thread(new B());
		t.start();
	}
}
  • 以上都是单线程,下面一个多线程的应用:
    卖票
public class ThreadDemo6 implements Runnable{
	int Ticket=5;
	@Override
	public void run() {
		for(int i=0;i<100;i++){
		if(Ticket>0){
		System.out.println(Thread.currentThread().getName()+"正在出售"+(Ticket--)+"车票");
		}
	}
	}
	public static void main(String[] args) {
		ThreadDemo6 t = new ThreadDemo6();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		Thread t3=new Thread(t);
		Thread t4=new Thread(t);
		t1.start();
		t2.start();
		t4.start();
		t3.start();
	}
}

有可能出现这样的现象:

5张车票,出售了6张
Thread-0正在出售5车票
Thread-2正在出售2车票
Thread-2正在出售1车票
Thread-3正在出售3车票
Thread-1正在出售4车票
Thread-0正在出售0车票

这样就用到了线程的同步
线程同步

  • 用到了:synchronized,这个可以是同步代码块,同步对象。
    线程同步的实现
public class ThreadDemo15 implements Runnable{
	int sum=5;
	@Override
	public synchronized void run() {
		for (int i = 0; i < 200; i++) {
			if(sum>0){
				System.out.println(Thread.currentThread().getName()+"出售"+sum--+"票");
				try {
					Thread.sleep(100);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	public static void main(String[] args) {
		ThreadDemo15 t = new ThreadDemo15();
		Thread t0 = new Thread(t);
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		Thread t3 = new Thread(t);
		t0.start();
		t1.start();
		t2.start();
		t3.start();
	}
}
  • 死锁
  • 同步可以保证资源共享操作的正确性,但是过多同步也会产生死锁, 死锁一般情况下表示互相等待,是程序运行时出现的一种问题。
  • 例如:
    想要画的张山跟想要书李四说:“把你的画给我,我把我的书给你”,李四也说:“把书给我,我把画给你”。然后俩个人互相等待
    线程间通信

    线程间通信的实现
public class communication01 {
    public static void main(String[] args){
        final besiness b=new besiness();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=1;i<=50;i++){
                    b.sub(i);
                }
            }
        }).start();
        for (int i = 1; i <= 50; i++) {
            b.main(i);
        }
    }
}
 class besiness{
     private static  boolean flag=true;//flag为true时允许main访问,为false时允许suB访问
        public synchronized void main(int i){
            while(!flag){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 1; j <= 10; j++) {
                System.out.println("main thread==" + j + ",loop of " + i);
            }
            flag=false;
            this.notify();
        }
        public  synchronized  void sub(int i){
            while (flag){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 1; j <= 10; j++) {
                System.out.println("sub thread==" + j + ",loop of " + i);
            }
            flag=true;
            this.notify();
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章