多线程(线程的概述,创建线程,控制线程,线程同步,线程池)

1.线程的概述

线程是:当一个程序运行时,内部可能包含了多个顺序的执行流,每个执行流就是一个线程。

线程与进程的区别:进程有独立的内存空间地址,线程共享内存空间地址

                  进程是静态的指令集,线程是动态的指令集

                  进程并行性,线程并发性

2.创建线程

方法一:继承Thread类来创建线程类

示例:

/**
 * 继承Thread,重写run()方法
 * 
 * @author Administrator
 * 
 */
public class Demo01 extends Thread {
	public static void main(String[] args) {
		Demo01 d1 = new Demo01();
		d1.start();
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);
		}

	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);
		}
	}

}


运行结果:


方法二:实现Runnable接口创建线程类

示例:

/**
 * 继承Runnable接口,重写 run()方法
 * @author Administrator
 *
 */
public class Demo02 implements Runnable {

	public static void main(String[] args) {
		Demo02 d = new Demo02();
		new Thread(d).start();//作为参数传给Thread对象
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);

		}

	}

	public void run() {

		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);

		}

	}

}

运行结果:


两者比较:

继承接口Runnable虽然比较麻烦,但是接口可以多继承,还可以继承其他的类,在实际运用中更多。


3.线程的生命周期

线程有新建,就绪,运行阻塞和死亡状态。具体关系如图所示

 

4.控制线程

1)join线程

  让一个线程等待另外一个线程完成。

示例:

public class Demo03 {
	public static void main(String[] args) {
		Thread a = new Thread(new A());
		Thread b = new Thread(new B());
		a.start();
		b.start();
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);
			if(i == 3){
				try {
					//主线程等待a,b线程执行完才执行
					a.join();
					b.join();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
			}
		
	}
		

	}

}

class A implements Runnable{

	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);
		
	}
	}
}

class B implements Runnable{

	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);
		
	}
		
	}
	
}

运行结果:


2)后台线程

后台线程是为其他线程服务的,其他线程停止后他也将停止。JVM中的垃圾回收线程是典型

的后台线程。

示例:

public class Demo03 {
	public static void main(String[] args) {
		Thread a = new Thread(new A());
		Thread b = new Thread(new B());
		a.start();
		b.setDaemon(true);//把b线程设为守护线程
		b.start();
	}
		

	}

class A implements Runnable{

	public void run() {
		for (int i = 0; i < 1; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);
		
	}
	}
}

class B implements Runnable{

	public void run() {
		while(true){
			System.out.println("我是B,守护线程!");
		}
	}
		
	}


运行结果:


3)线程休眠:sleep

让正在执行的的线程sleep一下,线程会发生阻塞,线程唤醒时则继续执行。

示例:

public class Demo03 {
	public static void main(String[] args) {
		Thread a = new Thread(new A());
		a.start();
		for (int i = 0; i < 3; i++) {

			System.out.println(Thread.currentThread().getName() + "--" + i);

		}
	}

}

class A implements Runnable {

	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);
			try {
				Thread.sleep(1000);//让线程睡眠1秒
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

运行结果:

 

4)线程让步:yield

让线程等待一下,并不会使线程发生阻塞,而是直接让线程进入就绪状态,让系统重新调度一下,也是完全有可能系统又重新调度了本线程。

示例:

public class Demo03 {
	public static void main(String[] args) {
		Thread a = new Thread(new A());
		a.start();
		for (int i = 0; i < 3; i++) {
			a.yield();//每执行一次主线程,让a线程等待一次
			System.out.println(Thread.currentThread().getName() + "--" + i);

		}
	}

}

class A implements Runnable {

	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);
			
		}
	}
}

运行结果:

 

5)改变线程的优先级

改变线程的优先级,优先级高的线程会得到更多的执行机会,但不绝对。

示例:

public class Demo03 {
	public static void main(String[] args) {
		Thread a = new Thread(new A());
		a.setPriority(10);//把a的优先级设成最高,得到更多的调度机会
		a.start();
		for (int i = 0; i < 3; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);

		}
	}

}

class A implements Runnable {

	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);
			
		}
	}
}

运行结果:

 


5.线程同步

1)同步代码块

示例:

public class Demo03 {
	public static void main(String[] args) {
		A a = new A();
		Thread t1 = new Thread(a);
		Thread t2 = new Thread(a);
		t1.start();
		t2.start();
		for (int i = 0; i < 3; i++) {
			System.out.println(Thread.currentThread().getName() + "--" + i);

		}
	}

}

class A implements Runnable {
	Object obj = 1;
	int a = 0;

	public void run() {
		synchronized (obj) { // 使用synchronized同步代码块
			for (int i = 0; i < 5; i++) {
				a++;
				System.out.println(Thread.currentThread().getName() + "--" + i
						+ "--" + a);

			}
		}

	}
}

运行结果:

 

2)同步方法

相当于同步代码块中,同步的对象为this,也就是说任意时刻只能有一个线程进入该对象中进行操作。

示例:

public class Demo03 {
	public static void main(String[] args) {
		A a = new A();
		Thread t1 = new Thread(a);
		Thread t2 = new Thread(a);
		t1.start();
		t2.start();
		
	}

}

class A implements Runnable {
	Object obj = 1;
	int a = 0;
	int b = 0;

	public void run() {
		math1();
		math2();
	}
	// 使用synchronized方法
	public synchronized void math1(){
		a++;
		System.out.println(Thread.currentThread().getName() +"我是a++" + a);
	}
	// 使用synchronized方法
	public synchronized void math2(){
		b--;
		System.out.println(Thread.currentThread().getName() +"我是b--" + b);
	}
}

运行结果:

 

3)同步锁

示例:

public class Demo03 {
	public static void main(String[] args) {
		A a = new A();
		Thread t1 = new Thread(a);
		Thread t2 = new Thread(a);
		t1.start();
		t2.start();
		
	}

}

class A implements Runnable {
	Object obj = 1;
	int a = 0;
	int b = 0;
	
	//定义锁对象
	private final ReentrantLock lock = new ReentrantLock();

	public void run() {
		math1();
	}
	
	public  void math1(){
		lock.lock();//加锁
		for (int i = 0; i <5; i++) {
			a++;
			System.out.println(Thread.currentThread().getName() +"我是a++" + a + "--" + i);
		} 
		
		lock.unlock();//释放锁
	}
	
}

运行结果:

 

4)死锁

当两个线程互相等待对方释放同步监视器的时候很容易发生死锁。

示例:

public class Demo05 implements Runnable {
	C c = new C();
	B b = new B();
	
	public void init(){
		c.cMathb(b);
	}
	public static void main(String[] args) {
		//主线程放在第一通常不会死锁,因为主线程的优先级比较高
		Demo05 d = new Demo05();
		new Thread(d).start();
		for(int i = 0; i < 100; i++){
			d.init();
		}
		
		

	}

	public void run() {
		for(int i = 0; i < 100; i++){
			b.bMathc(c);
		}
	}

}

class C {
	public synchronized void cMathb(B b) {
		b.math();
        System.out.println(Thread.currentThread().getName() + "--"+ "c中的cMathb()方法");
	}

	public synchronized void math() {
         System.out.println("c中的math方法");
	}

}

class B {
	public synchronized void bMathc(C c) {
		c.math();
		System.out.println(Thread.currentThread().getName() + " --"+ "c中的cMathb()方法");

	}

	public synchronized void math() {
		 System.out.println("b中的math()方法");
	}
}

运行结果:

 


6.线程池

Java5新增了Executor工厂类来实现生产线程池,开发者不需要手动实现自己的线程池。

示例:

public class Demo06 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ExecutorService pool = Executors.newFixedThreadPool(3);
		Runnable r =new Runnable() {
			public void run() {
				for (int i = 0; i < 10; i++) {
					System.out.println(Thread.currentThread().getName() + "--" + i);
				}
			}
		};
		
		pool.submit(r);
		pool.submit(r);
		pool.submit(r);
		//关闭线程池
		pool.shutdown();
	}

}

运行结果:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值