多线程基础

Thread线程介绍

线程简介

线程 是进程内的执行单元。

线程的基本操作

start-启动
同步块
synchronized
wait等待
notify通知
notify通知
wait等待
结束
NEW
RUNNABLE
BLOCKED
WAITING
TIMED-WAITING
TERMINATED
  • 新建线程
Thread t1 = new Thread();
t1.start();
//t1.run();//不能启动线程
Thread t1 = new Thread(){
	@Override
	public void run() {
		System.out.println("hello~ i am a new thread");
	}
};
t1.start();
Thread t1 = new Thread(new Runnable() {
		@Override
		public void run() {
			System.out.println("i am a runnable thread");
		}
});
t1.start();
  • 停止线程
    Thread.stop()
    不建议使用该方法,因为他会释放所有的moitor,而且这个方法是不安全的,已经被废弃了的方法
  • 中断线程
    Thread.interrupt()//中断线程
    Thread.isInterrupted()//判断是否被中断
public void run() {
	while(true) {
		Thread.yield();
	}
}

t1.interrupt();

如上代码一个线程t1的run方法中实现了一个while循环,在main主线程中调用t1.interrupt()方法中断此线程,interrupt其实就是给在正在运行的线程中发一个中断指令,正常理解线程t1应该中断,但其实并没有,线程t1仅仅是收到了主线程发送的一个指令,或者说是打了一个招呼,但是收到指令后怎么去做,并没有给出,线程t1仍然会继续执行循环。

很优雅的处理线程中断,需修改如下:

public void run() {
	while(true) {
		if(Thread.currentThread().isInterrupted()) {
			System.out.printli("t1 is interruted !")
			break;
		}
		Thread.yield();
	}
}
  • 等待线程
    Thread.sleep(long millis) throws InterruptedException
    这个方法很熟悉,会是当前线程等待 指定的时间 去执行,但会有InterruptedException异常抛出,因为程序会认为当正在线程等待的时候,没有做其它任务的逻辑处理,此时发生线程中断,也应该立即中断此线程,而无需继续等待

  • 线程挂起和继续执行
    Thread.suspend(); 线程挂起
    Thread.resume(); 继续执行
    这两种线程操作方法都是不推荐使用的方法。

为什么不推荐使用了呢?

如果一个线程t1中使用了一个对象锁,然后因为某种操作t1需要挂起suspend操作,在另一个线程t2中去操作t1继续执行resume(),由于是多线程操作,某些情况下可能会导致t2线程中执行的t1.resume()会发生在t1的挂起操作suspend之前,由于resume被先于执行,t1线程就会无限被挂起,而此时如果t3线程需要用到线程t1中同一个对象锁时,由于t1线程挂起,锁还未释放,这也会导致t3线程无法获取锁,也无法继续执行,导致非常尴尬的情况发生。

public class SuspendTest {
	public static Object u = new Object();
	static ChangeObjectThread t1 = new ChangeObjectThread("t1");
	static ChangeObjectThread t2 = new ChangeObjectThread("t2");

	public static class ChangeObjectThread extends Thread {
		public ChangeObjectThread(String name) {
			super.setName(name);
		}
		@Override
		public void run() {
			synchronized(u) {
				System.out.printli("in " + getName());
				Thread.currentThread().suspend();
			}
		}
	}

	public static void main(String[] arg) throws InterruptedException {
		t1.start();
		Thread.sleep(100);
		t2.start();
		t1.resume();
		t2.resume();
		t1.join();
		t2.join();
	}
}

上述代码中,main方法无法正常结束。

  • 等待线程结束(join)和 谦让(yeild)
    yeild方法是指将自己所占用的CPU或资源释放掉,然后和其他线程资源重新抢占资源的一个方法,并不是放弃了自己所占有的资源,使用此方法也还是有可能使当前线程获取资源并往下执行,只是给了其他线程重新获取资源的机会。

join()方法是等待调用该方法的线程执行结束,会有一个阻塞主线程的感觉,多个线程的join()操作相当于在主线程的汇聚。

public class JoinMain {
	public volatile static int i=0;
 	public static class AddThread extends Thread {
 		@Override
 		public void run() {
 			for(i=0;i<10000000;i++);
 		}
	}
	public static void main(String[] args) throws InterruptedException {
 		AddThread at=new AddThread();
 		at.start();
 		at.join();
 		System.out.println(i);
 	}
}

守护线程

在后台默默的完成一些系统性的服务,比如垃圾回收线程,JIT线程就可以理解为守护线程

当一个Java应用内,只有收回线程时,Java虚拟机就会自然退回出

Thread t=new DaemonT();
t.setDaemon(true);
t.start();

线程优先级

线程是可以设置优先级的,优先级高的线程更容易获取资源

Thread high=new HightPriority();
LowPriority low=new LowPriority();
high.setPriority(Thread.MAX_PRIORITY);
low.setPriority(Thread.MIN_PRIORITY);
low.start();
high.start();

基本线程同步操作

synchroinzed

  • 指定加锁对象:对给定对象加锁,进入同步代码前要获得给定对象的锁。
public class AccountingSync implements Runnable {
	static AccountingSync instance = new AccountingSync();
	static int i=0;
	@Override
	public void run() {
		for(int j=0; j<10000000; j++) {
			synchronized(instance) {
				i++;
			}
		}
	}
	public static void main(String[] arg) throws InterruptedException {
		Thread t1 = new Thread(instance);
		Thread t2 = new Thread(instance);
		t1.start(); t2.start();
		t1.join(); t2.join();
		System.out.println(i);
	}
}
  • 直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。
public class AccountingSync implements Runnable {
	static AccountingSync instance = new AccountingSync();
	static int i=0;
	public synchronized void increase() {
		i++;
	}
	@Override
	public void run() {
		for(int j=0; j<10000000; j++) {
			increase();
		}
	}
	public static void main(String[] arg) throws InterruptedException {
		Thread t1 = new Thread(instance);
		Thread t2 = new Thread(instance);
		t1.start(); t2.start();
		t1.join(); t2.join();
		System.out.println(i);
	}
}
  • 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。

Object.wait() Object.notify()
wait是线程等待在当前对象上,
notify通知等待在当前对象的线程,使从wait状态返回

wait 和 notify 必须使用在获取当前对象锁(监视器)中使用
wait执行当前等待后,会释放当前对象的监视器,供其他线程使用。

-------T1 -------------------------------T2--------------------
取得object监视器
object.wait();
释放object监视器
-----------------------------------取得object监视器
-----------------------------------object.notify();
等待object监视器 -----------释放object监视器
重新获取object监视器
释放object监视器

public class SimpleWN {
	final static Object obj = new Object();
	public static class T1 extends Thread {
		public void run() {
			synchrioized(obj) {
				System.out.println(System.currentTimeMillis() + ":T1 start !");
				try {
					System.out.println(System.currentTimeMills() + ":T1 wait for object");
					obj.wait();
				} catch(InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(System.currnetTimeMills() + ":T1 end !");
			}
		}
	}
	public static class T2 extends Thread {
		public void run() {
			synchrioized(obj) {
				System.out.println(System.currentTimeMillis() + ":T2 start ! notify noe thread ");
				obj.notify();
				System.out.println(System.currentTimeMills() + ":T2 end!");
				try {
					Thread.sleep(2000);
				} catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	public static void main(String[] args) {
		Thread t1 = new Thread();
		Thread t2 = new Thread();
		t1.start();
		t2.start();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值