JAVA的线程
一、创建线程
-
线程的两种创建方式
创建一个 java.lang.Thread类的实例
实现 java.lang.Runnable 接口
-
线程的实现
实现Thread 类
class A extends Thread{ public void run(){ while(true){ System.out.println("BBBB"); } } }
接口的实现
class A extends Thread{
public void run(){
while(true){
System.out.println("BBBB");
}
}
}
-
线程的创建
类线程的创建
A aa = new A(); aa.start();
接口线程的创建
A aa = new A(); Thread t = new Thread(aa); t.start();
线程的状态
-
新状态:线程对象已经创建,还没有在其上调用start()方法。
-
可运行状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态。当start()方法调用时,线程首先进入可运行状态。在线程运行之后或者从阻塞、等待或睡眠状态回来后,也返回到可运行状态。
-
运行状态:线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。
-
等待/阻塞/睡眠状态:这是线程有资格运行时它所处的状态。实际上这个三状态组合为一种,其共同点是:线程仍旧是活的,但是当前没有条件运行。换句话说,它是可运行的,但是如果某件事件出现,他可能返回到可运行状态。
-
死亡态:当线程的run()方法完成时就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
线程的优先级和线程让步 yield( )
Thread.yield() 方法暂停正在执行的线程对象,执行其他线程,线程的优先级在1~10 之间,通过setPriority( ) 修改线程的优先级
join( )方法让一个线程加入到另一个线程的尾部,在其执行完之前不能执行
二、线程的同步与锁
作用:线程的同步是为了防止多个线程访问同一个数据对象时,对数据造成破坏,例如银行取钱问题
同步和锁实现
- 锁的实现
/* Lock里面的代码只能一个线程使用后,另一个线程使用 */
import java.util.concurrent.locks.*;
class Window implements Runnable{
private int ticket = 100;
//实例化Lock
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true) {
try {
//调用锁定lock方法
lock.lock();
if(ticket > 0) {
try {
Thread.sleep(100);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": 售票,票号为" + ticket);
ticket--;
}else {
break;
}
}finally {
//调用解锁的方法
lock.unlock();
}
}
}
}
class Demo{
public static void main(String[] args) {
Window w = new Window();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
- 同步方法的实现
/* synchronized 02 */
class Window1 implements Runnable{
private int ticket = 100;
@Override
public void run(){
while(true){
show();
}
}
private synchronized void show(){
if(ticket > 0){
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + ticket);
ticket--;
}
}
}
class Thread04{
public static void main(String[] args){
Window1 w = new Window1();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t1.setName("窗口2");
t1.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
- 同步监视器
// implements Runnable --> run() --> synchronized()
class Window1 implements Runnable{
private int ticket = 100;
@Override
public void run(){
while(true){
synchronized(this){
if(ticket > 0){
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + ticket);
ticket--;
}else{
break;
}
}
}
}
}
class Thread03{
public static void main(String[] args){
Window1 w = new Window1();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("Windows1");
t2.setName("Windows2");
t3.setName("Windows3");
t1.start();
t2.start();
t3.start();
}
}
死锁问题
原因:两个线程调用对方资源,并且设置成对方执行完自己才能执行
class Demo{
public static void main(String[] args) {
StringBuffer s1 = new StringBuffer();
StringBuffer s2 = new StringBuffer();
new Thread() {
@Override
public void run() {
synchronized(s1) {
s1.append("a");
s2.append("1");
try {
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized(s2) {
s1.append("b");
s2.append("2");
System.out.println(s1);
System.out.println(s2);
}
}
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized(s2) {
s1.append("c");
s2.append("3");
try {
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized(s1) {
s1.append("d");
s2.append("4");
System.out.println(s1);
System.out.println(s2);
}
}
}
}).start();
}
}
三、线程的交互
void notify()
唤醒在此对象监视器上等待的单个线程。
void notifyAll()
唤醒在此对象监视器上等待的所有线程。
void wait()
导致当前的线程等待,直到其他线程调用此对象的 notify()方法或 notifyAll()方法。