------- android培训java培训、期待与您交流! ----------
死锁:一旦产生程序就停在那儿不动了,没法继续执行下去。
死锁的出现:同步中嵌套同步比如:同步函数中有同步代码块,同步代码块中有同步函数
面试的时候有可能让你写个死锁的例子:
下面给个线程死锁的例子:
class Test implements Runnable{
private boolean flag;
Test(boolean flag){
this.flag = flag;
}
public void run(){
if(flag){
synchronized (MyLock.locka) {
System.out.println("if locka");
synchronized (MyLock.lockb) {
System.out.println("if lockb");
}
}
}else{
synchronized (MyLock.lockb) {
System.out.println("else locka");
synchronized (MyLock.locka) {
System.out.println("else lockb");
}
}
}
}
}
class MyLock{
static Object locka = new Object();
static Object lockb = new Object();
}
public class DeadLockTest {
public static void main(String[] args) {
Thread t1 =new Thread(new Test(true));
Thread t2 =new Thread(new Test(false));
t1.start();
t2.start();
}
}
线程间通讯:其实就是多个线程在操作同一个资源,但是操作的动作不同
实现一个简单的小功能:一个往对象里面一直在加入东西一个一直往对象外面一直拿东西
只有存进去以后才能往外面拿,只有拿出了以后才能存
代码示例:
class Test implements Runnable{
private boolean flag;
Test(boolean flag){
this.flag = flag;
}
public void run(){
if(flag){
synchronized (MyLock.locka) {
System.out.println("if locka");
synchronized (MyLock.lockb) {
System.out.println("if lockb");
}
}
}else{
synchronized (MyLock.lockb) {
System.out.println("else locka");
synchronized (MyLock.locka) {
System.out.println("else lockb");
}
}
}
}
}
class MyLock{
static Object locka = new Object();
static Object lockb = new Object();
}
public class DeadLockTest {
public static void main(String[] args) {
Thread t1 =new Thread(new Test(true));
Thread t2 =new Thread(new Test(false));
t1.start();
t2.start();
}
}
唤醒全部线程的话可以用notifyAll();
wait(),notify(),notifyAll(),都使用在同步总,因为要对
持有监视器(锁)的线程操作,所以要使用在同步中,因为只有同步才具有锁。
为什么这些操作线程的方法要定义Object类中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁,
只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。
不可以对不同锁中的线程进行唤醒
也就是说,等待和唤醒必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义object类中
生产者消费者模式:
public class Test {
public static void main(String[] args) {
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
t1.start();
t2.start();
}
}
class Resource{
private String name ;
private int count =1;
private boolean flag = false;
public synchronized void set(String name ){
if(flag)
try {
this.wait();
} catch (Exception e) {
}
this.name = name +"---"+count++;
System.out.println(Thread.currentThread().getName()+"......生产者......."+this.name);
flag = true;
this.notify();
}
public synchronized void out(){
if(!flag)
try {
wait();
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+".......消费者....."+this.name);
flag = false;
this.notify();
}
}
class Producer implements Runnable{
private Resource res;
Producer(Resource res) {
this.res = res;
}
public void run(){
while(true){
res.set("+商品“+");
}
}
}
class Consumer implements Runnable{
private Resource res;
Consumer(Resource res) {
this.res = res;
}
public void run(){
while(true){
res.set("+商品“+");
}
}
}
这个程序在线程大于2的时候会出现问题
if(flag)当出现超过两个以上的线程时,容易唤醒本方,引文
if只执行一次,所以需要换成while(flag),而while(flag)容易出现死锁
所以这时需要this.notifyAll()唤醒所有等待的线程。
Lock实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作。
Lock是1.5以后升级才出现的
Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,
Condition 替代了 Object 监视器方法的使用。
使用lock和condition写生产者消费者模式
class Resource{
private String name ;
private int count =1;
private boolean flag = false;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void set(String name ) throws Exception{
lock.lock();
try {
while(flag)
condition .await();
this.name = name +"---"+count++;
System.out.println(Thread.currentThread().getName()+"......生产者......."+this.name);
flag = true;
}finally{
lock.unlock();
}
}
public synchronized void out(){
lock.lock();
try {
while(!flag)
condition.await();
System.out.println(Thread.currentThread().getName()+".......消费者....."+this.name);
flag = false;
} finally{
lock.unlock();
}
}
class Producer implements Runnable{
private Resource res;
Producer(Resource res) {
this.res = res;
}
public void run(){
while(true){
res.set("+商品“+");
}
}
}
Lock使用的官方文档:
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
如果需要定义只唤醒自己的,则可以定义多个condition
private Condition condition_pro = lock.newCondition();
private Condition condition_con = lock.newCondition();
condition_pro .await();
condition_con.signal();//唤醒对方的线程
线程的停止:stop方法已经过时,那么现在如何停止线程呢
只有一种方式,run方法结束,开启多线程运行,运行代码通常都是循环结构,
只要控制住循环,就可以让run方法结束,也就是线程结束。
特殊情况:当线程处于了冻结状态,就不会读取到标记,那么线程就不会结束。
当没有指定的方式让冻结的线程回复到运行状态时,这时需要对冻结进行清除
强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread类中提供了该方法叫:interrupt()可以让一个线程处于中断状态
Thread t2 = new Thread(t1);
t2.join();
t2抢夺线程的执行权,只有当t2这个线程运算完了以后主线程才能执行
join:当A线程执行到了B线程的.join()方法时,A就会等待,等
B线程执行完了以后才会执行A线程
join可以用来临时加入线程
setPriority()可以设置线程的优先级,主线程和其它线程默认的是5
优先级1、5、10最明显
MAX_PRIORITY(10) MIN_PRIORITY(1) NORN_PRIORITY(5)
yieId() 暂停当前正在执行的线程对象,并执行其他线程