Thread-线程

线程是程序里不同的执行路径

起一个新的线程,执行在run方法里面的程序


一、构造方法

推荐用实现接口,因为继承只能单继承

1.实现Runnable接口

package threadText;

public class TestThread1 {
	public static void main(String[] args){
		Runner1 r = new Runner1();
		//r.run();这样是方法的调用,不是线程
		Thread t = new Thread(r);//必须实例化一个Thread
		t.start();//必须调用start开始一个新的线程
		
		for(int i=0; i<100; i++){
			System.out.println("main"+ i);
		}
	}
}

class Runner1 implements Runnable{//比如重写run方法
	public void run(){
		for(int i=0; i<100; i++){
			System.out.println("Runner" + i);
		}
	}
}

2.继承Thread类

package threadText;

public class TestThread2 {
	public static void main(String[] args){
	Runner2 r = new Runner2();
	r.start();//因为r本身就是Thread类,所以可以直接调用
	for(int i = 0; i<100; i++){
		System.out.println("Main:" + i);	
	}
			
	}
}

class Runner2 extends Thread{//继承Thread类
	public void run(){
		for(int i=0; i<100; i++){
			System.out.println("Runner" + i);
		}
	}
}


二、sleep、join、 yeild方法

1.sleep方法

线程退出的一种方式,但是更好的方法是写一个flag

Thread静态方法,会抛出被打断的异常
package threadText;
import java.util.*;
public class TestInterrupt {
	public static void main(String[] args){
		MyThread thread = new MyThread();
		thread.start();
		try{
			Thread.sleep(10000);//使主进程暂睡眠
		}catch(InterruptedException e){}
		
		thread.interrupt();	//打断子进程
		
	}
}

class MyThread extends Thread{
	public void run(){
		while(true){
			System.out.println("===" + new Date() + "===");
			try{
				sleep(1000);
			} catch (InterruptedException e){
				return;//如果被打断结束子进程
			}
		}
	}
}

2.join方法

合并某个线程

package threadText;

public class TestJoin {
	public static void main(String[] args){
		MyThread2 t2 = new MyThread2("abcd");
		t2.start();
		try{
			t2.join();//将t2合并到线程,即执行完t2才执行主线程
		}catch(InterruptedException e){
			
		}
		for(int i = 0; i<10; i++){
			System.out.println("i am main Thread!");
		}
	}
}

class MyThread2 extends Thread{	
	MyThread2(String s){//构造方法,把s传递给super即Thread名称
		super(s);
	}
	
	public void run(){
		for(int i = 0; i<10; i++){
			System.out.println("i am:" + getName() );//getName是Thread里的方法
			try{
				sleep(1000);
			}catch(InterruptedException e){
				return;
			}
		}
	}
}

结果会执行完t2再执行主线程

3.yield方法

让出cpu让别的先执行

4.设置优先级

package threadText;

public class TestPriority {
	public static void main(String[] args){
		Thread t1 = new Thread( new T1() );
		Thread t2 = new Thread( new T2() );
		t1.setPriority(Thread.NORM_PRIORITY + 3);//当前的优先级加三
		t1.start();
		t2.start();
	}
}

class T1 implements Runnable{
	public void run(){
		for(int i = 0; i<100; i++){
			System.out.println("This is T1"+ i);
		}
	}
}

class T2 implements Runnable{
	public void run(){
		for(int i = 0; i<100; i++){
			System.out.println("T2" + i);
		}
	}
}

三、线程同步

一个线程在执行的过程中不会被另一个线程打断

package threadText;

public class TestSync implements Runnable{
	Timer timer = new Timer();
	public static void main(String[] args){
		TestSync test = new TestSync();
		Thread t1 = new Thread(test);
		Thread t2 = new Thread(test);
		t1.setName("t1");
		t2.setName("t2");
		t1.start();//两个访问的都是同一个timer文件
		t2.start();
	}
	public void run(){
		timer.add(Thread.currentThread().getName());//获得当前线程的名字传入
	}
}

class Timer{
	private static  int num = 0;
	public void add(String name){
		synchronized(this){//锁定这些方法,线程在使用它时被锁定,别的方法暂时不能用
		num++;
		try{
			Thread.sleep(100);
		}catch(InterruptedException e){}
		System.out.println(name+ "当前是第"+ num + "使用timer线程的");
		}
	}
}

锁定了当前的对象后,,睡眠的时候别的进程也不会再执行,不会再出现混乱

死锁

锁定时粒度太小,会使线程无法结束
/*
 * 死锁的产生是因为两个线程锁住对方完成的条件之一
 * 解决方法增加锁的粒度,即把整个方法都锁住,而不要锁小的方法
 */

package threadText;
public class DeadLock implements Runnable{
	public int flag = 1;
	static Object o1 = new Object();
	static Object o2 = new Object();
	
	public void run(){//重写run方法
		System.out.println("flag:" + flag);
		if(flag == 1){//用if区别两个线程的run方法
		synchronized(o1){
			try{
				Thread.sleep(10000);
			}catch(Exception e){
				e.printStackTrace();
			}
			synchronized(o2){
				System.out.println("1");//在锁死o2该线程完成
			}
		}
		}
		if(flag == 0){
			synchronized(o2){//上来就把o2锁住,两个线程谁也无法完成
				try{
					Thread.sleep(10000);
				}catch(Exception e){
					e.printStackTrace();
				}
				synchronized(o1){
					System.out.println("0");
				}
			}
		}
	}
	
	public static void main(String[] args){
		DeadLock td1 = new DeadLock();
		DeadLock td2 = new DeadLock();
		td1.flag = 1;
		td2.flag = 0;
		Thread t1 = new Thread(td1);
		Thread t2 = new Thread(td2);
		t1.start();
		t2.start();
	}
}

四、生产者消费者问题


package threadText;

public class ProducerConsumer {
	public static void main(String[] args){
		SynStack ss = new SynStack();
		Producer p = new Producer(ss); //两个线程同一个框
		Consumer c = new Consumer(ss);
		new Thread(p).start();
		new Thread(c).start();
	}
}

class WoTou{
	int id;
	WoTou(int id ){
		this.id = id;
	}
	public String toString(){//重写toString方法,方便显示
		return "WoTou" + id;
	}
}

class SynStack{//先进后出,用栈模拟篮子
	int index = 0;
	WoTou[] arrMT = new WoTou[6];
	
	public synchronized void push(WoTou wt){//同步,防止这个方法两条语句打断
		while(index == arrMT.length){//篮子满了就停止
			try{
				this.wait();//当前锁定在这个对象的线程停止,必须是锁定了以后才能wait
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
		this.notify();//叫醒正在wait上的线程
		arrMT[index] = wt;
		index++;
	}

	public synchronized WoTou pop(){//取馒头
		while(index == 0){//没有馒头了等待
			try{
			this.wait();
			}catch(InterruptedException e){
				e.printStackTrace();
			}
			}
		this.notify();
		index--;
		return arrMT[index];
	}
}

class Producer implements Runnable{//生产者类
	SynStack ss = null;
	Producer(SynStack ss){//构造方法,指定一个篮子生产
		this.ss = ss;
	}
	
	public void run(){//生产馒头
		for(int i = 0; i<20; i++){
			WoTou wt = new WoTou(i);
			ss.push(wt);//装入篮子
			System.out.println("生产了:" + wt);
			try{
				Thread.sleep(1000);
			}catch(InterruptedException e ){
				e.printStackTrace();
			}
		}
	}			
}

class Consumer implements Runnable{//生产者类
	SynStack ss = null;
	Consumer(SynStack ss){//构造方法,指定一个篮子拿出
		this.ss = ss;
	}
	
	public void run(){//消费馒头
		for(int i = 0; i<20; i++){
			WoTou wt = ss.pop();
			System.out.println("消费了:"+ wt);
			try{
				Thread.sleep(1000);
			}catch(InterruptedException e ){
				e.printStackTrace();
			}
		}
	}			
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值