b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

ccriticalsection 多线程 死锁_c# 线程死锁_linux 线程死锁

电脑杂谈  发布时间:2019-07-22 09:05:28  来源:网络整理

linux 线程死锁_ccriticalsection 多线程 死锁_c# 线程死锁

理解线程安全?

synchronized用法

死锁

中静态函数没有this指针(即在内存中静态函数和普通全局函数几乎没有什么区别),故可以匹配编译通过, 但是当线程函数要访问私有变量呢。属于同一进程的不同线程只有自己独有的私有栈与寄存器,公共分享占有堆与全局区,因此对于一般进程中的线程之间,局部变量是私有的,而静态局部变量,全局变量,分配在堆上的数据时共有的,因此针对这些数据的操作需要进行加密。 所以真正的读写数据都是在后端的mysql这里,在这里就使用多线程来操作全局数据(memcache的全局数据存在内存,而mysql的全局数据存在硬盘而已)~~而nginx仅仅是读取php脚本,而且各个php脚本都是相互独立的,所以读取时不需要同步之类的,所以这里用多线程和多进程都可以做到。

案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。

代码:

class ThreadTrain1 implements Runnable {
	// 这是货票总票数,多个线程会同时共享资源
	private int trainCount = 100;
	@Override
	public void run() {
		while (trainCount > 0) {// 循环是指线程不停的去卖票
try {
				// 等待100毫秒
				Thread.sleep(10);
			} catch (InterruptedException e) {
			}
			sale();
		}
	}
public void sale() {
		if (trainCount > 0) {
try {
				Thread.sleep(10);
			} catch (Exception e) {
			}
			System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
			trainCount--;		}
	}
}
public class ThreadDemo2 {
	public static void main(String[] args) {
		ThreadTrain1 threadTrain = new ThreadTrain1(); // 定义 一个实例
		Thread thread1 = new Thread(threadTrain, "一号窗口");
		Thread thread2 = new Thread(threadTrain, "二号窗口");
		thread1.start();
		thread2.start();
	}
}

运行结果:

在这里插入图片描述

一号窗口和二号窗口同时出售火车第一张和第七张,部分火车票会重复出售。

结论发现,多个线程共享同一个全局成员变量时,做写的操作可能会发生数据冲突问题。

问:如何解决多线程之间线程安全问题?

答:使用多线程之间同步或使用锁(lock)。

问:为什么使用线程同步或使用锁能解决线程安全问题呢?

4、当一个线程开始执行同步代码块时,并不意味着必须以不间断的方式运行,进入同步代码块的线程可以执行thread.sleep()或执行thread.yield()方法,此时它并不释放对象锁,只是把运行的机会让给其他的线程。4、 当一个线程开始执行同步代码块时,并不意味着必须以不间断的方式运行,进入同步代码块的线程可以执行thread.sleep()或者执行thread.yield()方法,此时它并不释放对象锁,只是把运行的机会让给其他的线程。当一个线程开始执行同步代码块时,并不意味着必须以不间断的方式运行,进入同步代码块的线程可以执行thread.sleep()或者执行thread.yield()方法,此时它并不释放对象锁,只是把运行的机会让给其他的线程。

问:什么是多线程之间同步?

答:当多个线程共享同一个资源,不会受到其他线程的干扰。

什么是同步代码块?

答:就是将可能会发生线程安全问题的代码,给包括起来。

synchronized(同一个数据){

可能会发生线程冲突问题

}

代码样例:

	private Object mutex = new Object();// 自定义多线程同步锁
	public void sale() {
		synchronized (mutex) {
			if (trainCount > 0) {
try {
					Thread.sleep(10);
				} catch (Exception e) {
				}
				System.out.println(Thread.currentThread().getName() + ",出售 第" + 
(100 - trainCount + 1) + "张票.");
				trainCount--;			}
		}
	}

什么是同步函数?

答:在方法上修饰synchronized 称为同步函数

代码样例

public synchronized void sale() {
			if (trainCount > 0) { 
try {
					Thread.sleep(40);
				} catch (Exception e) {
				}
				System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
				trainCount--;
			}
	}

同步函数用的是什么锁?

答:同步函数使用this锁。

线程进入同步代码块或同步函数前先判断锁标志位,若判断结果为真,则进入同步代码块或同步函数后,修改锁标志位为假,线程退出后,再恢复锁标志位为真。根据前面两条规则,我们可以知道,如果多个线程同时调用这个函数,当一个线程取得同步锁之后,其他线程就会阻塞在pthread_mutex_lock函数,而当那个取得锁的线程执行到pthread_cond_wait并阻塞之后,在从这个函数返回(条件满足)之前,会释放掉锁,所以其他线程也能一个一个都执行到pthread_cond_wait这里阻塞。3、当一个线程已经获取该object对象的synchronized(this)同步方法(或代码块)的锁时,该对象被类锁修饰的同步方法(或代码块)仍然可以被其他线程在同一cpu周期内获取,两种锁不存在资源竞争情况。

代码:

class ThreadTrain5 implements Runnable {
	// 这是货票总票数,多个线程会同时共享资源
	private int trainCount = 100;
	public boolean flag = true;
	private Object mutex = new Object();
	@Override
	public void run() {
		if (flag) {
			while (true) {
				synchronized (mutex) {
					if (trainCount > 0) {
try {
							Thread.sleep(40);
						} catch (Exception e) {
						}
						System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
						trainCount--;
					}
				}
			}
		} else {
			while (true) {
				sale();
			}
		}
	}
	
	public synchronized void sale() {
		if (trainCount > 0) {
			try {
				Thread.sleep(40);
			} catch (Exception e) {
			}
			System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
			trainCount--;
		}
	}
}
public class ThreadDemo5 {
	public static void main(String[] args) throws InterruptedException {
		ThreadTrain5 threadTrain = new ThreadTrain5(); // 定义 一个实例
		Thread thread1 = new Thread(threadTrain, "一号窗口");
		Thread thread2 = new Thread(threadTrain, "二号窗口");
		thread1.start();
		Thread.sleep(40);
		threadTrain.flag = false;
		thread2.start();
			}
}

答:什么是静态同步函数?

方法上加上static关键字,使用synchronized 关键字修饰 或者使用类.class文件。

静态的同步函数使用的锁是 该函数所属字节码文件对象

可以用 getClass方法获取,也可以用当前 类名.class 表示。

代码样例:

synchronized (ThreadTrain.class) {
			System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
			trainCount--;
			try {
				Thread.sleep(100);
			} catch (Exception e) {
			}
}

总结:

synchronized 修饰方法使用锁是当前this锁。

synchronized 修饰静态方法使用锁是当前类的字节码文件

答:同步中嵌套同步,导致锁无法释放

代码:

class ThreadTrain6 implements Runnable {
// 这是货票总票数,多个线程会同时共享资源
	private int trainCount = 100;
	public boolean flag = true;
	private Object mutex = new Object();
	@Override
	public void run() {
		if (flag) {
			while (true) {
				synchronized (mutex) {
					// 锁(同步代码块)在什么时候释放? 代码执行完, 自动释放锁.
					// 如果flag为true 先拿到 obj锁,在拿到this 锁、 才能执行。
					// 如果flag为false先拿到this,在拿到obj锁,才能执行。
					// 死锁解决办法:不要在同步中嵌套同步。
					sale();
				}
			}
		} else {
			while (true) {
				sale();
			}
		}
	}
public synchronized void sale() {
		synchronized (mutex) {
			if (trainCount > 0) {
				try {
					Thread.sleep(40);
				} catch (Exception e) {
				}
				System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
				trainCount--;
	}
		}
	}
}
public class DeadlockThread {
	public static void main(String[] args) throws InterruptedException {
		ThreadTrain6 threadTrain = new ThreadTrain6(); // 定义 一个实例
		Thread thread1 = new Thread(threadTrain, "一号窗口");
		Thread thread2 = new Thread(threadTrain, "二号窗口");
		thread1.start();
		Thread.sleep(40);
		threadTrain.flag = false;
		thread2.start();
	}
}


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-114832-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...