Java知识总结-多线程


说明:关于多线程,同步问题是我有待加强的知识点。

一、线程的创建。

创建线程可以通过两种方式:

方式一,自定义一个类,继承Thread类并重写run()方法。例:

//自定义类继承Thread类
class MyThread extends Thread{
	//重写run()方法
	public void run(){
		System.out.println("重写run()方法");
	}
}
public class Test {
	public static void main(String[] args){
		//创建Thread子类对象
		MyThread mt=new MyThread();
		//通过调用start()方法,开启新线程,同时执行run()方法
		mt.start();
	}
}

方式二,自定义一个类,实现Runnable接口。

//自定义类实现Runnable接口
class MyClass implements Runnable{
	//重写run()方法
	public void run(){
		System.out.println("重写run()方法");
	}
}
public class Test {
	public static void main(String[] args){
		//创建Runnable子类对象
		MyClass mc=new MyClass();
		//将对象作为参数传入Thread的构造函数,创建Thread类对象
		Thread t=new Thread(mc);
		//通过调用Thread类的start()方法,开启新线程,同时执行run()方法
		t.start();
	}
}
上面创建线程的两种方式里,方式二可以避免Java中单继承的问题,当一个类有父类时,可以通过实现Runnable接口来定义线程。


二,线程的操作

在Thread类中,有些常见的操作线程的方法。

------getName():返回该线程的名称,返回值类型:String。

//自定义类实现Runnable接口
class MyClass implements Runnable{
	//重写run()方法
	public void run(){
		System.out.println("重写run()方法");
	}
}
public class Test {
	public static void main(String[] args){
		//创建Runnable子类对象
		MyClass mc=new MyClass();
		//将对象作为参数传入Thread的构造函数,创建Thread类对象
		Thread t=new Thread(mc);
		//获取线程名称
		System.out.println(t.getName());
	}
}

运行结果:

Thread-0

这时返回的线程名称是系统默认的名称,也可以通过getName()方法自定义线程的名称。

------setName(String name):改变线程名称,使之与参数name相同。

//自定义类实现Runnable接口
class MyClass implements Runnable{
	//重写run()方法
	public void run(){
		System.out.println("重写run()方法");
	}
}
public class Test {
	public static void main(String[] args){
		//创建Runnable子类对象
		MyClass mc=new MyClass();
		//将对象作为参数传入Thread的构造函数,创建Thread类对象
		Thread t=new Thread(mc);
		//自定义线程名称
		t.setName("自定义线程 Myclass");
		//获取线程名称
		System.out.println(t.getName());
	}
}


运行结果:

自定义线程 Myclass

这时线程的名称就变为我们设置的名字。


------sleep(long millis):使正在执行的线程休眠(暂停执行),返回值类型:void;静态方法。

注,该方法已经声明异常,当我们在run()方法内调用sleep()时,需要对异常已经处理,因为Thread类中的run()方法并没有抛出异常,所以重写run()时也不可以抛出异常,只能对异常进行try{}catch{}处理。

class MyClass extends Thread{
	public void run(){
		for(int x=0;x<100;x++){
			try {
				//使线程休眠20毫秒
				sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}	
			System.out.println(Thread.currentThread().getName());
		}
	}
}

-------wait():使当前线程等待。返回值类型:void;

注:如果当前线程被wait()方法操作导致等待时,该线程会自动放弃在CPU中的执行权和执行资格,系统CPU会随机执行其他具备执行资格的线程。

class MyClassA extends Thread{
	public void run(){
		
		for(int x=0;x<100;x++){
			
				try {
					if(x==10)
					//使线程等待
					wait();
				} catch (InterruptedException e) {
					//异常处理
					e.printStackTrace();
				}
			System.out.println(Thread.currentThread().getName());
		}
	}
}


------notify():唤醒与当前线程同步的线程中的单个等待线程;

------notifyAll():唤醒与当前线程同步的线程中的所有等待线程;

------interrupt():中断线程的休眠和等待状态,使线程继续运行。

------join():等待该调用线程执行完毕后,原线程继续执行。

------setDaemon():将该线程标记为守护线程,当主线程运行结束时,守护线程随之结束。

------setPriority(int newPriority):更改线程的优先级。

------yiekd(): 暂停当前线程,并执行其他线程。


三,同步

当多个线程共享同一资源时,

同步的前提:

1.必须要有两个或者两个以上的线程;

2.必须是多个线程使用同一个锁。

同步的作用:通过同步是多个线程只能有一个线程在运行,

好处:解决了多线程的安全问题;

弊端:多个线程需要判断锁,较为消耗资源。

同步实例:

例1:简单的同步代码块结构

class MyClass implements Runnable{
	public void run(){
		synchronized (this) {
		    System.out.println("需要同步的代码");
		}
	}
}

注:synchronized代码块中锁可以是任意对象。

 例2:多线程操作同一数据(线程功能相同)

class MyClass extends Thread{
	private static int x=0;
	public void run(){
		while(x<=100){
			synchronized (Test.class) {
				if(x<=100){
					System.out.println(Thread.currentThread().getName()+"--"+"x="+x);
					x++;
				}
			}
		}
	}
}
public class Test {
	public static void main(String[] args){
		MyClass mc1=new MyClass();
		MyClass mc2=new MyClass();
		mc1.start();
		mc2.start();
	}
}
例3:多线程操作同一数据(线程功能不同)
class Resource{
    //产品名称,编号,标记
	private String name;
	private int count = 1;
	private boolean flag = false;	
	//生产者
    public synchronized void set(String name){	
		if(flag)
			try{
                wait();
            }
            catch (Exception e){               
            }
		this.name  = name+"--"+count++;
		String aa = Thread.currentThread().getName();
		String bb = this.name;
		System.out.println(aa+"..生产者.."+bb);
		flag = true;
		this.notify();
	}
    //消费者
	public synchronized void out(){
		if(!flag)
			try{
                wait();
            }
            catch (Exception e){
            }
		String aa = Thread.currentThread().getName();
		String bb = this.name;
		System.out.println(aa+"...消费者.."+bb);
		flag = false;
		this.notify();	
	}
}
//生产者类实现Runnable接口
class Producer implements Runnable{
	private Resource res;
	Producer(Resource res){
		this.res = res;
	}
	public void run(){
		while(true){
			res.set("商品");
		}
	}
}
//消费者实现Runnable接口
class Consumer implements Runnable{
	private Resource res;
	Consumer(Resource res){
		this.res = res;
	}
	public void run(){
		while(true){
			res.out();
		}
	}
}
class  ProducerConsumerDemo{
	public static void main(String[] args){
		Resource r = new Resource();
		new Thread(new Producer(r)).start();
		new Thread(new Consumer(r)).start();
	}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值