一、死锁问题:
死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。
比如,线程一需要第一把所,此时锁处于空闲状态,给了线程一,线程二需要第二把所,第二把锁也处于空闲状态,给了线程二,这样是没问题的。
但是,当线程一需要第一把所,线程二需要第二把所后未归还,线程一又需要第二把锁,此时线程一就会一直等待线程二将锁归还,可线程二还是需要线程一的锁,也处于等待的状态,因此,线程一和线程二都保持循环等待,两个线程都无法做完事情归还锁,二者出现死锁情况。。。
package com.Gary1; public class DeadLock { public static Object lock1 = new Object();
public static Object lock2 = new Object(); public static void main(String[] args) { new Thread(new Thread1()).start();
new Thread(new Thread2()).start(); } } class Thread1 implements Runnable{ @Override
public void run() {
synchronized(DeadLock.lock1) {
System.out.println("取得第一把锁之后要做的事情");
try {
//耗时100毫秒,继续做一些事情
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(DeadLock.lock2) {
System.out.println("Thread1同时取得两把锁之后要做的事情");
}
} }
} class Thread2 implements Runnable{ @Override
public void run() {
synchronized(DeadLock.lock2) {
System.out.println("取得第二把锁之后要做的事情");
try {
//耗时100毫秒,继续做一些事情
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(DeadLock.lock1) {
System.out.println("Thread2同时取得两把锁之后要做的事情");
}
} }
}
DeadLock.java
避免这种情况出现最好的方法:解决上锁的顺序
两边线程上锁顺序lock1->lock2
package com.Gary1; public class DeadLock { public static Object lock1 = new Object();
public static Object lock2 = new Object(); public static void main(String[] args) { new Thread(new Thread1()).start();
new Thread(new Thread2()).start(); } } class Thread1 implements Runnable{ @Override
public void run() {
synchronized(DeadLock.lock1) {
System.out.println("取得第一把锁之后要做的事情");
try {
//耗时100毫秒,继续做一些事情
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(DeadLock.lock2) {
System.out.println("Thread1同时取得两把锁之后要做的事情");
}
} }
} class Thread2 implements Runnable{ @Override
public void run() {
synchronized(DeadLock.lock1) {
System.out.println("取得第二把锁之后要做的事情");
try {
//耗时100毫秒,继续做一些事情
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(DeadLock.lock2) {
System.out.println("Thread2同时取得两把锁之后要做的事情");
}
} }
}
DeadLock.java
二、线程组ThreadGroup 默认处于同一个组里面
使用线程组可以统一设置这个组内线程的一些东西。比如设置优先级,设置是否是守护线程
ThreadGroup tg = new ThreadGroup("我们的线程组"); Thread t1 = new Thread(tg,r);
Thread t2 = new Thread(tg,r); //批量管理
tg.interrupt();//中断里边所有线程
tg.setDaemon(true);//设置守护线程
tg.setMaxPriority(9);//设置线程组最大优先级
package com.Gary1; public class ThreadGroupDemo { public static void main(String[] args) {
MyRunnable r = new MyRunnable(); ThreadGroup tg = new ThreadGroup("我们的线程组"); Thread t1 = new Thread(tg,r);
Thread t2 = new Thread(tg,r); //批量管理
tg.interrupt();//中断里边所有线程
tg.setDaemon(true);//设置守护线程
tg.setMaxPriority(9);//设置线程组最大优先级 //ThreadGroup tg = t1.getThreadGroup();
//输出线程名字
//System.out.println(tg.getName());
//输出线程组名字
//System.out.println(t2.getThreadGroup().getName()); t1.start();
t2.start(); } }
ThreadGroupDemo.java
package com.Gary1; public class MyRunnable implements Runnable{ private String data = ""; @Override
public void run() {
for(int i=0;i<100;i++) {
Thread t = Thread.currentThread();
System.out.println(t.getName()+":"+i);
} } }
MyRunnable.java
三、定时器Timer
作用:一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。
使用类:Timer和TimerTask
常用方法:
timer.schedule(TimerTask task, long delay)
timer.schedule(TimerTask task, long delay, long period)
timer.schedule(TimerTask task, Date time)
timer.cancel();
public static void main(String[] args) {
//Timer TimerTask
Timer t = new Timer(); //定义一个定时器任务,2000毫秒开始执行
//t.schedule(new MyTimerTask(), 2000);
//定义一个定时器任务,2000毫秒开始执行,每个3000毫秒执行一次
//t.schedule(new MyTimerTask(), 2000,3000);
//在哪个时间开始执行这个任务
//t.schedule(new MyTimerTask(), time);
//终止定时器任务执行
//timer.cancel();
}
package com.Gary1; import java.util.Timer;
import java.util.TimerTask; public class TimerDemo {
public static void main(String[] args) {
//Timer TimerTask
Timer t = new Timer(); //定义一个定时器任务,2000毫秒开始执行
//t.schedule(new MyTimerTask(), 2000);
//定义一个定时器任务,2000毫秒开始执行,每个3000毫秒执行一次
//t.schedule(new MyTimerTask(), 2000,3000);
//在哪个时间开始执行这个任务
//t.schedule(new MyTimerTask(), time);
//终止定时器任务执行
//timer.cancel();
} } class MyTimerTask extends TimerTask{ @Override
public void run() {
System.out.println("定时器任务"); } }
TimerDemo.java