Java多线程学习之实现方式

一、实现多线程的方式

1.继承Thread类

步骤:

A:自定义MyThread类继承Thread类;

B:重写run()方法,包含被线程执行的代码;

C:创建对象;

D:启动线程

package thread;

public class ThreadPriority extends Thread{
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i = 0; i < 100; i++){
			System.out.println(getName()+"--"+i);
		}
	}
}
package thread;

public class ThreadPriorityDemo {
	public static void main(String[] args) {
		ThreadPriority tp1 = new ThreadPriority();
		ThreadPriority tp2 = new ThreadPriority();
		ThreadPriority tp3 = new ThreadPriority();
		
		//设置线程优先级,最大值为10,最小为1,默认为5
		tp1.setPriority(10);
		tp2.setPriority(1);
		
		//start()方法启用线程
		tp1.start();
		tp2.start();
		tp3.start();
	}
}

2.实现Runnable接口

步骤:

A:自定义类MyRunnable实现Runnable接口;

B:重写run()方法;

C:创建MyRunnable类的对象;

D:创建Thread类对象,把上一步创建的类对象当作构造参数

package thread;

public class MyRunnable implements Runnable {
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i = 0; i < 100; i++){
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
}
package thread;

public class MyRunnableDemo {
	public static void main(String[] args) {
		MyRunnable my = new MyRunnable();  
		
		Thread t1 = new Thread(my);
		Thread t2 = new Thread(my);
		
		t1.start();
		t2.start();
	}
}

 

二、多线程模拟出售电影票

1.使用同步解决线程安全问题

package thread;

public class SellTicket implements Runnable{
	//定义100张票
	private int tickets = 100;
	//定义同一把锁
	private Object obj = new Object();
	
	@Override
	public void run() {
		while(true){
                        //同步
			synchronized (obj) {
				if(tickets > 0){
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {					
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
				}
			}
		}	
	}
}
package thread;

public class SellTicketDemo {
	public static void main(String[] args) {
		SellTicket st = new SellTicket();
		
		Thread t1 = new Thread(st,"窗口1");
		Thread t2 = new Thread(st,"窗口2");
		Thread t3 = new Thread(st,"窗口3");
		
		t1.start();
		t2.start();
		t3.start();
	}
}

 还可以把同步代码块写成同步方法,这时锁对象是这个方法--this。//synchronized (this)

package thread;

public class SellTicket implements Runnable{
	//定义100张票
	private int tickets = 100;
	//定义同一把锁
	private Object obj = new Object();
	
	@Override
	public void run() {
		while(true){
			sellTicket();			
                }	
	}
	
	private synchronized void sellTicket(){
		if(tickets > 0){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {					
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
		}
	}
}

当方法时静态时,锁对象是类的字节码文件对象,即当前类的class文件。 //synchronized(SellTicket.class)

package thread;

public class SellTicket implements Runnable{
	//定义100张票
	private static int tickets = 100;
	//定义同一把锁
	private Object obj = new Object();
	
	@Override
	public void run() {
		while(true){
			sellTicket();
		}	
	}
	
	private static synchronized void sellTicket(){
		if(tickets > 0){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {					
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
		}
	}
}

2.使用lock解决线程安全问题

package thread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SellTicketLock implements Runnable{
	private int tickets = 100;
	private Lock lock = new ReentrantLock();
	
	@Override
	public void run() {
		while(true){
			try{
				lock.lock(); //加锁
				if(tickets > 0){
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
				}
			}finally{
				lock.unlock();
			}
		}
	}
}
package thread;

public class SellTicketDemo {
	public static void main(String[] args) {
		SellTicketLock st = new SellTicketLock();
		
		Thread t1 = new Thread(st,"窗口1");
		Thread t2 = new Thread(st,"窗口2");
		Thread t3 = new Thread(st,"窗口3");
		
		t1.start();
		t2.start();
		t3.start();
	}
}

 把不安全的list集合安全的使用:

List<String> list1 = new ArrayList<String>();   //线程不安全
List<String> list2 = Collections.synchronizedList(new ArrayList<String>());  //线程安全

三、生产者消费者之等待唤醒机制

package pv;

public class Student {
	private String name;
	private int age;
	private boolean flag;	//默认为false,若为true,则有数据
	
	public synchronized void set(String name,int age){
		//若果有数据,就等待
		if(this.flag){
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//设置数据
		this.name = name;
		this.age = age;
		//修改标记
		this.flag = true;
		this.notify(); 
	}
	
	public synchronized void get(){
		//如果没有数据,就等待
		if(!this.flag){
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println(this.name+"---"+this.age);
		this.flag = false;
		this.notify();
	}
}
package pv;

public class Set implements Runnable{
	private Student s;
	private int x = 0;
	
	public Set(Student s){
		this.s = s ;
	}
	@Override
	public void run() {
		while(true){
			if(x % 2 == 0){
				s.set("yj", 23);
			}else{
				s.set("kryie", 25);
			}
			x++;
		}
	}
}
package pv;

public class Get implements Runnable{
	private Student s; 
	
	public Get(Student s){
		this.s = s ;
	}
	@Override
	public void run() {
		while(true){
			s.get();
		}
	}
}
package pv;

public class StudentDemo {
	public static void main(String[] args) {
		//创建资源
		Student s = new Student();
		//设置资源、获取资源
		Set st = new Set(s);
		Get gt = new Get(s);
		//线程类
		Thread t1 = new Thread(st);
		Thread t2 = new Thread(gt);
		//启动线程
		t1.start();
		t2.start();
	}
}

猜你喜欢

转载自blog.csdn.net/weufengwangshi_/article/details/81544608