Java之线程

目录

创建线程

继承Thread类来创建线程 

实例 

 创建Thread类对象来创建线程

实例

 实现Runnable接口来创建线程 

实例

Thread类的常用方法

Thread类的构造方法 

public Thread()

public Thread(String name)

public Thread(Runnable target)

public Thread(Runnable target,String name)

Thread类常用的方法  

getName()获取某个进程的进程名称

setName()修改某个进程的进程名称

Thread.currentThread()获取当前线程的对象

isAlive()确认某个线程是否存活

getPriority()获取某个线程的优先权

setPriority()设定某个线程的优先权

sleep()线程的延时函数

实例

线程同步

同步的机制

实例(没有使用synchronized关键字锁住共享资源时)

实例(使用synchronized关键字锁住共享资源时) 

线程的等待和唤醒

wait()

notify()

notifyAll()

实例

 


 

创建线程

继承Thread类来创建线程 

class Athread extends Thread {
        public void run(){} 
}

public class Text {
        public static void main(String[] args) {
                new Athread().start();  //启动线程
        }    
}

 

实例 

//继承THread类来创建线程
class Athread extends Thread {

	public void run(){  //重写Thread类的run()方法,该方法在调用Thread类的start()方法时自动执行
		while(true){
			System.out.println("我是线程A");
			try {
				Thread.sleep(1000);  //使用Thread类的静态方法,延时函数将线程A挂起1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Bthread extends Thread {

	public void run(){
		while(true){
			System.out.println("我是线程B");  
			try {
				Thread.sleep(1000);  
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

public class Text {
	public static void main(String[] args) {
	
		new Athread().start();  //启动线程A
		new Bthread().start();  //启动线程B
	
	}	
}

 创建Thread类对象来创建线程

public class Text {
        public static void main(String[] args) {

                Thread Athread = new Thread() {
                         public void run() {}  
                };

        Athread.start();  //启动线程A 
        }
}

实例

public class Text {
	public static void main(String[] args) {

		//创建Thread类对象
		Thread Athread = new Thread() {
			public void run() {  //重写Thread类的run()方法,该方法在调用Thread类的start()方法时自动执行
				while(true){
					System.out.println("我是线程A");
					try {
						Thread.sleep(1000);  //使用Thread类的静态方法,延时函数将线程A挂起1s
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};

		Thread Bthread = new Thread() {
			public void run() {
				while(true){
					System.out.println("我是线程B");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		
		Athread.start();  //启动线程A
		Bthread.start();  //启动线程B
		
	}
}

 实现Runnable接口来创建线程 

class AThread implements Runnable {  //实现Runnable接口
        public void run() {}   
}


public class Text {
        public static void main(String[] args) {
                Thread a = new Thread(new AThread());
                 a.start();  //启动线程
        }
}

实例

class AThread implements Runnable {
	
	public void run() {
		while(true){
			System.out.println("我是线程A");
			try {
				Thread.sleep(1000);  //使用Thread类的静态方法,延时函数将线程A挂起1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} 
	}
}

class BThread implements Runnable {
	
	public void run() {
		while(true){
			System.out.println("我是线程B");
			try {
				Thread.sleep(1000);  //使用Thread类的静态方法,延时函数将线程A挂起1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} 
	}
}

public class Text {
	
	public static void main(String[] args) {
	
		Thread a = new Thread(new AThread());
		a.start();
		
		Thread b = new Thread(new BThread());
		b.start();
		
	}
}

Thread类的常用方法

Thread类的构造方法 

public Thread()

创建一个Thread对象

public Thread(String name)

创建一个Thread对象,参数name是设定线程对象的名称。

Thread t1 = new Thread("线程1")  //设定线程对象名称为线程1

public Thread(Runnable target)

创建一个Thread对象,参数target是Runnable接口类型的对象,此构造方法将实现Runnable接口的类的对象放在Thread对象中,启动线程时会执行target对象的run()方法。

class AThread implements Runnable {  //实现Runnable接口
        public void run() {}   
}


public class Text {
        public static void main(String[] args) {
                Thread a = new Thread(new AThread());
                a.start();  //启动线程
        }
}

public Thread(Runnable target,String name)

创建一个Thread对象,参数name是设定线程对象的名称,参数target是Runnable接口类型的对象。

Thread类常用的方法  

getName()获取某个进程的进程名称

Thread a = new Thread();

a.getName();  //获取某个进程的线程名称

setName()修改某个进程的进程名称

Thread a = new Thread(String);

a.setName();  //修改某个进程的线程名称

Thread.currentThread()获取当前线程的对象

Thread a = new Thread(); 
Thread.currentThread();  //获取当前线程的对象

isAlive()确认某个线程是否存活

Thread a = new Thread(); 
a.isAlive(); //确认线程是否存活,如果存活返回true,如果死亡返回false 

getPriority()获取某个线程的优先权

Thread a = new Thread(); 
a.getPriority();  //获取某个线程的优先权,默认为5 

setPriority()设定某个线程的优先权

Thread类的优先权常量:

  • Thread.MIN_PRIORITY:数值为1,最低优先权
  • Thread.NORM_PRIORITY :数值为5,默认优先权
  • Thread.MAX_PRIORITY:数值为10,最高优先权

Thread a = new Thread(); 

a/​​​​​​.setPriority(int);  //设定某个线程的优先权,默认为5,最低为1,最高为10,处于就绪队列中的线程优先权越高,越先被执行

sleep()线程的延时函数

Thread a = new Thread(); 
Thread.sleep(int);  //让线程挂起(延时)一段毫秒时间

实例

public class Text {
	
	static int cnt = 0;
	
	static public void inspectThread(Thread obj){  
		if(obj.isAlive() == true){  //isAlive()确认线程是否存活,如果存活返回true,如果死亡返回false
			System.out.println("线程还活着");
		}else if(obj.isAlive() == false){
			System.out.println("线程已经死了");
		}else{
			System.out.println("不知道线程的状态");
		}
	}
	
	public static void main(String[] args) {
		
		Thread a = new Thread("线程1"){
			public void run() {
				while(true){
					System.out.println("jiangxiaoya");
					cnt += 1;
					if(cnt == 5){
						break;
					}
					try {
						Thread.sleep(3000);  //sleep()线程的延时函数:将线程A挂起3s
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		System.out.println(a.getName());  //getName()获取某个进程的线程名称
		a.setName("myThread");  //setName()修改某个进程的线程名称
		System.out.println(a.getName());  
		Thread.currentThread().setName("线程1");  //Thread.currentThread()获取当前线程的对象
		
		
		a.start();  
		inspectThread(a);
		
		System.out.println(a.getPriority());  //getPriority()获取某个线程的优先权,默认为5
		a.setPriority(9);  //setPriority()设定某个线程的优先权,默认为5,最低为1,最高为10,处于就绪队列中的线程优先权越高,越先被执行
		try{
			a.join();  //等待线程对象a的线程执行完毕
		}catch (InterruptedException e) {
			e.printStackTrace();
		}
		inspectThread(a);  
	}	
}

2abe25b1a8e94b5cb076747813f78f19.png

线程同步

线程同步主要是为了避免同一个时间点有多个线程同时访问同一个共享资源(例如对象)而造成的数据错误。

同步的机制

Java的关键字synchronizedH会把程序块锁入一个房间中,房间每次只能允许一个线程进入,线程对象进入房间前会去房间门口领取钥匙。例如A线程是第一个访问这个房间的,那么A线程就直接领取房间门口的钥匙进入房间,后面的线程B和线程C也来到房间门口,但线程B和线程C需要阻塞等待(进入中断状态)线程A从房间出来归还钥匙后才能领取钥匙进入房间。

实例(没有使用synchronized关键字锁住共享资源时)

class myThread implements Runnable {
	
	int grabed;  //已经偷得的金条数量
	static int totalGold = 200000;  //金条总数
	Thread t;
	
	public myThread(String name) {  //构造方法
		t = new Thread(this,name);  //this == (t1)new myThread();
		t.start();  //启动线程
	}
	
	private static boolean grabGold() {  //判断金条是否剩余,如果剩余还能偷取
		if(totalGold > 0){
			totalGold--;  //偷取一条金条
			return true;
		}else {
			return false;
		}
	}
	
	public void run() {
		while(grabGold()){
			grabed++;  //获得一条金条
		} 
		System.out.println(t.getName() + "总共偷得金条" + grabed +"条");
	}
}

public class Text {
	
	public static void main(String[] args) {
	
		System.out.println("共有金条" + myThread.totalGold +"条");
		myThread t1 = new myThread("A");  //创造线程A去偷金条
		myThread t2 = new myThread("B");  //创造线程B去偷金条
		myThread t3 = new myThread("C");  //创造线程C去偷金条
		
	}
}

d3170cdaa1114e20a3e566a23ba1b8f8.png

实例(使用synchronized关键字锁住共享资源时) 

class myThread implements Runnable {
	
	int grabed;  //已经偷得的金条数量
	static int totalGold = 200000;  //金条总数
	Thread t;
	
	public myThread(String name) {  //构造方法
		t = new Thread(this,name);  //this == (t1)new myThread();
		t.start();  //启动线程
	}
	//当使用synchronized关键字将金条(共享资源)放进一个房间时,一次只能由一个线程偷取
	private synchronized static boolean grabGold() {  //判断金条是否剩余,如果剩余还能偷取
		if(totalGold > 0){
			totalGold--;  //偷取一条金条
			return true;
		}else {
			return false;
		}
	}
	
	public void run() {
		while(grabGold()){
			grabed++;  //获得一条金条
		} 
		System.out.println(t.getName() + "总共偷得金条" + grabed +"条");
	}
}

public class Text {
	
	public static void main(String[] args) {
	
		System.out.println("共有金条" + myThread.totalGold +"条");
		myThread t1 = new myThread("A");  //创造线程A去偷金条
		myThread t2 = new myThread("B");  //创造线程B去偷金条
		myThread t3 = new myThread("C");  //创造线程C去偷金条
		
	}
}

44325170564745ffbb6bdcf48aabade2.png

线程的等待和唤醒

Object对象中提供wait()、notify()、notifyAll()方法可以让线程间相互设定等待或者唤醒。

wait()

让指定的线程进入等待队列成为等待状态。wait()方法必须写在synchronized程序块中,并用try...catch捕获异常。另外,为避免其他线程执行notify()方法或notifyAll()方法时唤醒不能唤醒的线程,所谓wait()方法必须写在while等循环中,并配合满足循环的条件。

notify()

唤醒一个在等待队列等待的线程,哪个线程被唤醒则由JVM决定。

notifyAll()

唤醒所有在等待队列等待的线程,哪个线程会先执行则由JVM决定。

实例

 

class Baseball {
	private boolean isThrow = false;  //棒球初始状态为未投出
	
	public synchronized void pBall(int tNo){  //投球机
		
		while(isThrow){  //如果已经投球就等待击打者打球
			try{
				wait();  //进入等待状态
			} catch (InterruptedException e){}
		}
		//投球
		System.out.println("投出第 " + tNo + " 颗棒球");
		isThrow = true;  
		notify();  //唤醒击打者

	}
	
	public synchronized void hBall(int aNo){  //击打
		while(!isThrow){  //如果已经打球就等待投球机投球
			try{
				wait();  //进入等待状态
			} catch (InterruptedException e){}
		}
		//打球
		System.out.println("第 " + aNo + " 次挥棒");
		isThrow = false;  
		notify();  //唤醒投球机
	}
}


class Pitching implements Runnable {
	
	Baseball  baseball;
	Pitching(Baseball baseball){
		this.baseball = baseball;
	}
	
	public void run() {
		for (int i = 1; i <= 5; i++){  //投5次球
			baseball.pBall(i);  
		}	
	} 
}

class Hit implements Runnable {
	
	Baseball  baseball;
	Hit(Baseball baseball){
		this.baseball = baseball;
	}
	
	public void run() {
		for (int i = 1; i <= 5; i++){  //打5次球
			baseball.hBall(i);
		}	
	} 
}


public class Text {
	
	public static void main(String[] args) {
	
		Baseball baseball = new Baseball();  //
		
		Thread A = new Thread(new Pitching(baseball));  //A线程投球
		Thread B = new Thread(new Hit(baseball));  //B线程打球
		A.start();
		B.start();
		
	}
}

ef0de3c983564c5185bdc5aebe3d06e6.png

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值