java 多线程学习笔记2-同步代码块,死锁
2016-12-18 15:08
429 查看
1、多线程-同步代码块:synchronized
当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步。
如果两段代码是同步的, 那么同一时间只能执行一段, 在一段代码没执行结束之前, 不会执行另外一段代码。
synchronized关键字加上一个锁对象就可以同步代码,这个锁对象可以是任意的一个对象,只要求是同一个就行。
例如:
class Printer {
Demo d = new Demo();
public static void print1() {
synchronized(d){
System.out.print("你");
System.out.print("好");
System.out.print("呀");
System.out.print("\r\n");
}
}
public static void print2() {
synchronized(d){
System.out.print("C");
System.out.print("S");
System.out.print("D");
System.out.print("N");
System.out.print("\r\n");
}
}
}
class Demo{ //创建一个任意的class,用来做锁对象
public Demo(){}
}
现在在主函数里面创建2条线程执行:如果不加synchronized(d),可能输出print1 和print2就会出现乱序的问题(你好呀CS)。
final Printer p = new Printer();
new Thread(){
public void run(){ //重写Thread类里面的run方法
p.print1();
}
}.start(); //启动一个线程
new Thread(){
public void run(){ //重写Thread类里面的run方法
p.print1();
}
}.start(); //启动第二个线程
2、多线程-同步方法:synchronized
使用synchronized关键字修饰一个方法, 该方法中所有的代码都是同步的
例如:
class Printer {
public static synchronized void print1() {
//这里的锁对象就是Printer.class(字节码对象) ,锁对象可以是任意的,但必须是同一把锁
System.out.print("你");
System.out.print("好");
System.out.print("呀");
System.out.print("\r\n");
}
public static void print2() {
synchronized(Printer.class){
//这里使用Printer.class(字节码对象)对象作为锁对象
System.out.print("C");
System.out.print("S");
System.out.print("D");
System.out.print("N");
System.out.print("\r\n");
}
}
}
注意:
非静态同步函数的锁是:this (因为创建的对象是同一个,此时的this就代表new的那个对象)
静态static的同步函数的锁是:字节码对象(因为使用 类名.方法 调用 ,类名是同一个)
3、多线程-线程安全:
多线程并发操作同一数据时, 就有可能出现线程安全问题,使用同步技术可以解决这种问题, 把操作数据的代码进行同步, 不要多个线程一起操作
class TicketsSeller extends Thread {
private static int tickets = 100;//定义一个私有静态变量
static Object obj = new Object();//定义一个锁对象
public TicketsSeller() {
super();
}
public TicketsSeller(String name) {
super(name);
}
public void run() {
while(true) {
synchronized(obj) {//如果没有锁的话,就可能出现多个线程同时操作了tickets这个变量,导致if多次判断0后,还进行了--操作,导致负号票出现
if(tickets <= 0)
break;
System.out.println(getName() + "...这是第" + tickets-- + "号票");
}
}
}
}
//伪代码,创建4个线程调用
t1.start();
t2.start();
t3.start();
t4.start();
3、多线程-死锁:
多线程同步的时候, 如果同步代码嵌套, 使用相同锁, 就有可能出现死锁,所以尽量不要嵌套使用。
private static String s1 = "left";//定义一个锁对象s1
private static String s2 = "right";//定义一个锁对象s2
public static void main(String[] args) {
new Thread() {
public void run() {
while(true) {
synchronized(s1) {
System.out.println(getName() + "get" + s1 + "wait" + s2);
synchronized(s2) { //有可能执行到这个地方的时候,s2被下面线程使用,未释放,就拿不到s2了
System.out.println(getName() + "get" + s2 + "OK");
}
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
synchronized(s2) {
System.out.println(getName() + "get" + s2 + "wait" + s1);
synchronized(s1) { //执行到这个地方,s1被上面线程使用,未释放,线程就一直卡在这了
System.out.println(getName() + "get" + s1 + "OK");
}
}
}
}
}.start();
}
4、多线程-常用线程安全类有哪些:看源码,有synchronized修饰的方法或代码块就是线程安全的
Vector是线程安全的,ArrayList是线程不安全的
StringBuffer是线程安全的,StringBuilder是线程不安全的
Hashtable是线程安全的,HashMap是线程不安全的
当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步。
如果两段代码是同步的, 那么同一时间只能执行一段, 在一段代码没执行结束之前, 不会执行另外一段代码。
synchronized关键字加上一个锁对象就可以同步代码,这个锁对象可以是任意的一个对象,只要求是同一个就行。
例如:
class Printer {
Demo d = new Demo();
public static void print1() {
synchronized(d){
System.out.print("你");
System.out.print("好");
System.out.print("呀");
System.out.print("\r\n");
}
}
public static void print2() {
synchronized(d){
System.out.print("C");
System.out.print("S");
System.out.print("D");
System.out.print("N");
System.out.print("\r\n");
}
}
}
class Demo{ //创建一个任意的class,用来做锁对象
public Demo(){}
}
现在在主函数里面创建2条线程执行:如果不加synchronized(d),可能输出print1 和print2就会出现乱序的问题(你好呀CS)。
final Printer p = new Printer();
new Thread(){
public void run(){ //重写Thread类里面的run方法
p.print1();
}
}.start(); //启动一个线程
new Thread(){
public void run(){ //重写Thread类里面的run方法
p.print1();
}
}.start(); //启动第二个线程
2、多线程-同步方法:synchronized
使用synchronized关键字修饰一个方法, 该方法中所有的代码都是同步的
例如:
class Printer {
public static synchronized void print1() {
//这里的锁对象就是Printer.class(字节码对象) ,锁对象可以是任意的,但必须是同一把锁
System.out.print("你");
System.out.print("好");
System.out.print("呀");
System.out.print("\r\n");
}
public static void print2() {
synchronized(Printer.class){
//这里使用Printer.class(字节码对象)对象作为锁对象
System.out.print("C");
System.out.print("S");
System.out.print("D");
System.out.print("N");
System.out.print("\r\n");
}
}
}
注意:
非静态同步函数的锁是:this (因为创建的对象是同一个,此时的this就代表new的那个对象)
静态static的同步函数的锁是:字节码对象(因为使用 类名.方法 调用 ,类名是同一个)
3、多线程-线程安全:
多线程并发操作同一数据时, 就有可能出现线程安全问题,使用同步技术可以解决这种问题, 把操作数据的代码进行同步, 不要多个线程一起操作
class TicketsSeller extends Thread {
private static int tickets = 100;//定义一个私有静态变量
static Object obj = new Object();//定义一个锁对象
public TicketsSeller() {
super();
}
public TicketsSeller(String name) {
super(name);
}
public void run() {
while(true) {
synchronized(obj) {//如果没有锁的话,就可能出现多个线程同时操作了tickets这个变量,导致if多次判断0后,还进行了--操作,导致负号票出现
if(tickets <= 0)
break;
System.out.println(getName() + "...这是第" + tickets-- + "号票");
}
}
}
}
//伪代码,创建4个线程调用
t1.start();
t2.start();
t3.start();
t4.start();
3、多线程-死锁:
多线程同步的时候, 如果同步代码嵌套, 使用相同锁, 就有可能出现死锁,所以尽量不要嵌套使用。
private static String s1 = "left";//定义一个锁对象s1
private static String s2 = "right";//定义一个锁对象s2
public static void main(String[] args) {
new Thread() {
public void run() {
while(true) {
synchronized(s1) {
System.out.println(getName() + "get" + s1 + "wait" + s2);
synchronized(s2) { //有可能执行到这个地方的时候,s2被下面线程使用,未释放,就拿不到s2了
System.out.println(getName() + "get" + s2 + "OK");
}
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
synchronized(s2) {
System.out.println(getName() + "get" + s2 + "wait" + s1);
synchronized(s1) { //执行到这个地方,s1被上面线程使用,未释放,线程就一直卡在这了
System.out.println(getName() + "get" + s1 + "OK");
}
}
}
}
}.start();
}
4、多线程-常用线程安全类有哪些:看源码,有synchronized修饰的方法或代码块就是线程安全的
Vector是线程安全的,ArrayList是线程不安全的
StringBuffer是线程安全的,StringBuilder是线程不安全的
Hashtable是线程安全的,HashMap是线程不安全的
相关文章推荐
- 学习笔记 java多线程 信号量(Semaphore),死锁
- [原]Java多线程编程学习笔记之八:死锁(含代码)
- [原]Java多线程编程学习笔记之八:死锁(含代码)
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
- java个人学习笔记17(synchronized+同步函数+同步代码块+死锁)
- 学习java多线程的笔记1--Thread(Runnable t)与重写run()方法等
- Java多线程学习笔记1
- 学习笔记7—Java基础5_多线程
- 学习笔记 - java.util.concurrent 多线程框架(引)
- 学习java多线程的笔记5--初体验
- 训练营学习笔记 java多线程(五)生产者/消费者
- java多线程学习笔记3
- Java 死锁的实现 -Java学习笔记(28)
- Java学习笔记9——多线程
- 黑马程序员之JAVA学习笔记:多线程学习大总结
- 学习笔记 java多线程(四)线程间协作
- Java 多线程编程 学习笔记
- [零散篇]Java学习笔记---Java的Socket网络编程以及多线程
- java学习日记(6)____多线程的安全问题与死锁的产生
- C\C++ 程序员从零开始学习Android - 个人学习笔记(十) - java基础 - 多线程(待续)