Java多线程的测试

Java多线程的测试

一、通过继承Thread类方式创建线程

  • 步骤:创建一个Thread类,或者一个Thread子类的对象,即通过继承Thread类的方式创建线程类,重写run()方法。

  • 例子:线程1和线程2竞争获取cpu资源,两者获得cpu资源具有不确定性,是随机获取资源的

package com.imooc.thread;

class MyThread extends Thread{
    
    MyThread(String name){
        super(name);
    }
    public void run() {
        for(int i = 0; i<10;i++) {
            System.out.println(getName() + "正在执行" + i);
        }
    }
}
/**
  * 测试线程1和线程2竞争获取cpu资源,两者获得cpu资源具有不确定性,是随机获取资源的
 */
public class ThreadTest1 {
    
    public static void main(String[] args) {
        MyThread mt1 = new MyThread("线程1");
        MyThread mt2 = new MyThread("线程2");
        mt1.start();
        mt2.start();
    }
}

二、测试Thread类的join() 和 join(x ms)方法

  • 带参数的join方法:public final void join(long millis)

  • 作用:调用join(x)方法的线程,优先执行x毫秒,x时间一过,丧失优先级,其他线程可以竞争cpu资源执行。

package com.imooc.thread;

class MyThread2 extends Thread{
	public void run() {
		for(int i =1;i<=300;i++) {
			System.out.println(getName()+"线程真正执行" + i +"次");
		}
	}
}

/**
 * 带参数的join方法:public final void join(long millis)
 * 调用join(x)方法的线程,优先执行x毫秒,x时间一过,丧失优先级,其他线程可以竞争cpu资源执行。
*/

public class JoinDemo {
	public static void main(String[] args) {
		MyThread2 mt = new MyThread2();
		mt.start();
		
		try {
			//mt线程执行1ms后,丧失优先级,主线程开始竟争资源,然后执行
			mt.join(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		for(int i=1;i<=20;i++) {
			System.out.println("主线程执行第" + i +"次");
		}
		
		int main = Thread.currentThread().getPriority();
		System.out.println(main);
		mt.setPriority(Thread.MAX_PRIORITY);
	}
}

三、通过实现Runnable接口创建线程

步骤(三步):类实例化,根据实例化的对象创建线程类,线程子类调用start方法

package com.imooc.runnable;

public class PrintRunnable implements Runnable {

	//成员变量,共享资源 
	int i = 1;
	//run方法被多个线程共享,这个例子中被t1和t2线程共享,t1和t2共运行10次
	//适合多个线程处理同一个资源
	public void run() {
		while(i<=10) {
			//注意,实现runnable接口的类中,不能直接使用getName方法,因为getName方法是Thread类的方法
			System.out.println(Thread.currentThread().getName() + "正在运行" + (i++));
		}
		
	}

/**
 *  通过实现Runnable接口创建线程有3步,类实例化,根据实例化的对象创建线程类,线程子类调用start方法
 *  
 */
	public static void main(String[] args) {
		//类实例化,分配类的实例,在创建Thread时作为参数传递
		PrintRunnable pr = new PrintRunnable();
		//根据实例化的对象创建线程类
		Thread t1 = new Thread(pr);
		//线程子类调用start方法
		t1.start();
		
		//PrintRunnable pr1 = new PrintRunnable();
		Thread t2 = new Thread(pr);
		t2.start();
	}

}

四、线程间的通信和同步

1565860395354

package com.imooc.queue;
//消费者类,不断消耗n值
public class Consumer implements Runnable{
	//消费者和生产者共享queue
	Queue queue;
	//构造方法
	Consumer(Queue queue){
		this.queue=queue;
	}

	@Override
	public void run() {
		while(true){
			//不断获取queue的n值
			queue.get();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}	
}

package com.imooc.queue;

//生产者类,不断生产n值
public class Producer implements Runnable{
	//生产者和消费者共享queue 
	Queue queue;
	//构造方法
	Producer(Queue queue){
		this.queue=queue;
	}
	@Override
	public void run() {
		int i=0;
		//这里用了一个死循环,一直输出
		while(true){
			//修改共享queue的n值
			queue.set(i++);
			try {
				//休眠1s
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}	
	}
}
package com.imooc.queue;

public class Queue {
	
	private int n;
	boolean flag=false;
	//flag为false的时候,容器queue中没有数据,需要先生产后获取
	//为true时,有数据,需要先获取再生产
	
	//get方法,获得n的值
	//要加上同步关键字,保证共享资源queue同一时间只有一个线程访问
	public synchronized int get() {
		//flag为false时,没有数据,需要执行等待
		if(!flag){
			try {
				//等待set生成资源
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("消费:"+n);
		flag=false;//消费完毕,容器中没有数据
		notifyAll();//唤醒其他线程
		//一般使用这个,因为实际中可能不知道该唤醒哪一个,那把它们都唤醒。
		return n;
	}
	//set方法,设置n的值
	public synchronized void set(int n) {
		//当flag为true,即容器中有数据时,不要再生产了,等待消费完再生产
		if(flag){
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("生产:"+n);
		this.n = n;
		flag=true;//生产完毕,容器中已经有数据
		notifyAll();//唤醒其他线程,否则会引起死锁
	}
}

package com.imooc.queue;

public class Test {

	public static void main(String[] args) {
		Queue queue=new Queue();
		//实现runnable接口,创建线程三步走,连起来写
		new Thread(new Producer(queue)).start();
		new Thread(new Consumer(queue)).start();
	}

}
posted @ 2019-08-15 16:42  ContinDo  阅读(775)  评论(0编辑  收藏  举报