多线程系列之创建线程

先来两个例子,回顾启动线程两种方法:

1、实现Runnable接口

Runnable 接口只有一个方法。run()方法。

Thread newThread= new Threadtarget);//target是接口类型

Runnablerun方法可以使用Thread的静态方法

 

public class ThreadTest1 {

	//实现Runnable,实现run方法
	    public static void main(String[] args) {		
		Runner1 runner1=new Runner1();
		Thread th=new Thread(runner1);
		th.start();//启动其他线程必须有start()方法
		
		for(int i=0;i<20;i++){
			System.out.println("main方法线程----------:"+i);
		}
	}
	
	static class  Runner1 implements Runnable{
		public void run(){

			for(int i=0;i<20;i++){
				System.out.println("Runner:"+i);
			}			
		}		
	}
}

2、子类继承Thread,重写run方法;再实例化子类

class MyThread extends Thread{

public void run(){。。。}

} 

MyThread myThread=new MyThread();

public class ThreadTest1 {
	//继承Thread 重写run方法
	public static void main(String[] args) {		
		Runner1 runner1=new Runner1();
		runner1.start();
		
		for(int i=0;i<20;i++){
			System.out.println("main方法线程----------:"+i);
		}
	}
	
	static class  Runner1 extends Thread{
		public void run(){

			for(int i=0;i<20;i++){
				System.out.println("Runner:"+i);
			}			
		}		
	}
}

线程概念

单线程的程序只有一个顺序执行流;

多线程的程序可以包含多个顺序执行流,多个顺序流之间互不干扰;

一句话:线程是程序里不同的执行路径;

进程是分配资源单位,静态的;线程是调度、执行单位,动态的;

线程的优势

线程是共享的环境:进程代码段、进程的公有数据等。

线程可以共享内存,进程不能;

多线程实现多任务比多进程的效率高;

java语言内置了多线程功能支持,而不是单纯的作为底层操作系统的调度方式,从而简化java的多线程编程。


线程创建和启动

Thread类代表线程,所有线程对象都是这个类或子类的实例。

run()代表线程要完成的任务,即线程执行体

start()启动多线程

main()主方法,代表主线程的线程执行体,默认的

Thread.currentThread():静态方法,返回当前正在执行的线程

getName():获取线程名,例如Thread-0Thread-1

创建:集成Thread类,实现RunnableCallable接口,可以实现多线程

生命周期

就绪态、运行态、等待态


状态转换

线程死亡:线程正常结束、抛出异常或错误;

stop()方法来结束线程,容易导致死锁,通常不推荐使用,

isAlive()检查线程生命


控制线程

join()让一个线程等待另一个线程,把分支线程再合并回来。

/**
 * join合并线程
 * @author bobo
 * 未合并前,main方法先执行完,再执行t2
 *把t2合并回来,直到t2执行完了,再执行main方法
 */
public class TestJoin {

	public static void main(String[] args) {
		
		MyThread2 t2 = new MyThread2("t2");
		t2.start();
		
		try {
			t2.join();
		} catch (InterruptedException e) {
			
		}
		for(int i=0;i<=10;i++){
			System.out.println("i am mian Thread");
		}
	}
	
	public static class MyThread2 extends Thread{
		MyThread2 (String s){
			super(s);
		}
		public void run(){
			for(int i=0;i<=10;i++){
				System.out.println("i am " +getName());
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					return;
				}
			}			
		}
	}

}

Sleep()线程睡眠

public synchronized void method() throws Exception {
		Thread.sleep(2500);//睡眠2.5秒,这期间其他线程不能占用
		b = 2000;
	}
	

yield()线程让步

/**
 * 让出cpu一会,让给其他线程执行一会儿
 * @author bobo
 *
 */
public class testYield {

	public static void main(String[] args) {
		MyThread3 t1 = new MyThread3("t1");
		MyThread3 t2 = new MyThread3("t2");
		
		t1.start();
		t2.start();
	}
	
	static class MyThread3 extends Thread{
		MyThread3(String s){
			super(s);
		}
		public void run(){
			for(int i=0;i<=100;i++){
				System.out.println(getName()+":"+ i);
				System.out.println(Thread.currentThread().isAlive());
				if(i % 10==0){
					yield();//让出cpu
				}
			}
		}
	}
}

线程同步和死锁

Synchronized关键字,保证共享数据的完整性。保证在任一时刻只能有一个线程访问。

1public snchronizedvoid add(){}//当前方法锁定

2synchronizedthis{//锁机制,锁定当前,保证了原子性,不会有第二个线程进来打断}

/**
 * 同步,两个线程,一个的执行要拿到另一个线程给的资源,否则就是阻塞状态
 * @author bobo
 *
 */
public class TestSynchronized implements Runnable {
	Timer t=new Timer();
	public static void main(String[] args) {
		TestSynchronized test=new TestSynchronized();
		Thread t1=new Thread(test);
		Thread t2=new Thread(test);
		t1.setName("T1");
		t2.setName("T2");
		
		t1.start();
		t2.start();
	}
	
	static class Timer{
		private static int num=0;
		public synchronized void add(String name){
			num++;
			try{
				Thread.sleep(100);
			}catch(InterruptedException e){
				
			}
			System.out.println(name+",你是第【"+num+"】个使用timer的线程!");
		}
	}

	@Override
	public void run() {
		t.add(Thread.currentThread().getName());		
	}
}

死锁

我的理解是:当多个线程有共享资源,但是互相等待对象释放资源。

    下面例子产生了死锁,两个线程都抓着资源不放,等待对方释放资源,但最终谁也等不到,而产生了死锁。

public class TestDeadLock implements Runnable {

	public int flag=1;
	static Object o1=new Object(),o2=new Object();
	
	@Override
	public void run() {
		System.out.println("flag="+flag);
		if(flag==1){
			synchronized(o1){
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					
					e.printStackTrace();
				}
				synchronized(o2){
					System.out.println("11");
				}
			}
		}
		if(flag==0){
			synchronized(o2){
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					
					e.printStackTrace();
				}
				synchronized(o1){
					System.out.println("00");
				}
			}
		}
	}

	public static void main(String[] args) {
		TestDeadLock dl=new TestDeadLock();
		TestDeadLock dl2=new TestDeadLock();
		
		dl.flag=1;
		dl2.flag=0;
		
		Thread t1=new Thread(dl);
		Thread t2=new Thread(dl2);
		
		t1.start();
		t2.start();

	}

}

以上是线程的基本知识,后面还会有很多地方会用到多线程,再一一介绍,既然有同步,就会有一个种生产者消费者的情况产生,后一个介绍,生产者和消费者的例子。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值