欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java多线程-线程状态及方法的使用

程序员文章站 2022-05-05 16:34:38
...


Java多线程-线程状态及方法的使用

 

thread.sleep(int)  让线程进入休眠状态。如果在synchronized代码块或方法中执行sleep(int),线程并不会放弃对象的锁。

 

object.wait()  :让当前获得object对象锁的线程进入该对象的线程等待队列。也就是让线程解开这个对象的锁, 同时进入休眠状态。wait状态的线程可被object.notify()唤醒。

 

object.notify()  :从object对象的线程等待队列中随机唤醒一个线程。被唤醒的线程从object.wait()的位置继续往下执行。

 

object.notifyAll()  :从object对象的线程等待队列中唤醒所有线程。

 

生产者和消费者模式:

package com.xinxin.mytest;

import java.util.ArrayList;
import java.util.List;

public class TestThread {
	
	public static void main(String[] args){
		Pool pool = new Pool();
		Producer p1 = new Producer(pool, "p1");
		Producer p2 = new Producer(pool, "p2");
		Consumer c1 = new Consumer(pool, "c1");
	
		p1.start();
		p2.start();
		c1.start();
	}
}

class Producer extends Thread{
	Pool pool;
	String name;
	
	public Producer(Pool pool, String name){
		this.pool=pool;
		this.name=name;
	}
	
	@Override
	public void run(){
		try{
			while(true){
				int a = this.pool.add();
				System.out.println(String.format("name= %s add=%d", name, a));
				//Thread.sleep(500);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

class Consumer extends Thread{
	Pool pool;
	String name;
	
	public Consumer(Pool pool, String name){
		this.pool=pool;
		this.name=name;
	}
	
	@Override
	public void run(){
		try{
			while(true){
				int a = this.pool.del();
				System.out.println(String.format("name= %s del=%d", name, a));
				Thread.sleep(100);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

class Pool{
	int MaxSize=3;
	int index=0;
	List<Integer> list = new ArrayList<Integer>();
	
	public synchronized int add() throws Exception{
		while(list.size()>=MaxSize){
			this.wait();
		}
		list.add(++index);
		System.out.println("add size="+list.size());
		this.notify();
		return index;
	}
	
	public synchronized int del() throws Exception{
		while(list.size()==0){
			this.wait();
		}
		int res = list.remove(0);
		System.out.println("del size="+list.size());
		this.notify();
		return res;
	}	
}

 上面的代码有个bug:当MaxSize=1时,三个线程p1、p2、p3可能同时进入wait状态,永不被唤醒。解决的办法,将this.notify()改成this.notifyAll()或this.notify(1000)

 

 

Thread.yield(); 谦让的意思,暂时解开该线程的CPU占用权,由其他线程有更多机会使用CPU。此方法可解决线程快速切换过程中某个线程集中占用CPU的问题。 

 

thread.setDaemon(true); 设置线程为守护线程,当其他非守护线程结束后,守护线程会自动结束。前提是守护线程要放在死循环中,否则守护线程会先结束。 

 

thread.setPriority(int proority); 设置线程优先级 事实并不能保证线程运行的优先级,所以一般不使用。一般使用共享变量控制线程的运行。

 

synchronized 修饰方法或者代码块,方法或代码块中的代码只能被同步访问。修饰动态方法时以当前类对象this作为锁,修饰静态方法时以类修饰符class作为锁。

 

thread1.join() 等待线程thread1执行完后继续当前线程的执行。

 

package com.xinxin.mytest;

public class TestJoin {
	
	public static void main(String[] args){
		Player p1 =new Player("tom",3);
		Player p2 =new Player("peter",5);
		Player p3 =new Player("terry",9);

		p1.start();
		p2.start();
		p3.start();
		
		try {
			p1.join();
			p2.join();
			p3.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("斗地主可以开始了!");
	}
}

class Player extends Thread{
	String name;
	int waitTime;
	
	Player(String name, int waitTime){
		this.name=name;
		this.waitTime=waitTime;
	}
	
	@Override
	public void run(){
		try{
			System.out.println(this.name+" is comming!");
			Thread.sleep(this.waitTime*1000);
			System.out.println(this.name+" is arrived!");
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

  执行结果

tom is comming!

terry is comming!

peter is comming!

tom is arrived!

peter is arrived!

terry is arrived!

斗地主可以开始了!:

 

停止线程:

1. 使用共享变量作为循环结束标记

因为线程运行代码一般都是循环,只要控制了循环即可。

2.  thread.interrupt() 中断

结束线程的冻结状态,使线程回到运行状态。简单粗暴,很少使用。

3.  thread.stop() 终止线程 已被弃用