- 进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该程序是一个执行路径,或者叫一个控制单元。
- 线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。
- 一个进程中至少有一个线程。
- Java VM 启动的时候会有一个进程java.exe.
- 该进程中至少一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称之为主线程。扩展:其实更细节说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程。
1.如何在自定义的代码中,自定义一个线程呢?通过对api的查找,java已经提供了对线程这类事物的描述。就Thread类。
创建线程的第一种方式:继承Thread类。
步骤:
1.定义类集成Thread。
2.复写Thread类中的run方法。目的:将自定义的代码存储在run方法。让线程运行。
3.调用线程的start方法。该方法有两个作用:启动线程,调用run方法。
发现运行结果每一次都不同。因为多个线程都获取cpu的执行权。cpu执行到谁,谁就运行。明确一点,在某一个时刻,只能有一个程序在执行。(多核除外)cpu在坐着快速的切换,以达到看上去是同时运行的效果。我们可以形象的把多线程的运行行为比作是在互相抢夺cpu的执行权。这就是多线程的一个特性:随机性。谁抢到谁执行,至于执行多长,cpu说了算。
为什么要覆盖run方法呢?
Thread类用于描述线程。该类就定义了一个功能,用于存储线程要运行的代码。该存储功能就是run方法。也就是说Thread类中的run方法,用于存储线程要运行的代码。
class Demo4 extends Thread
{
public void run()
{
for (int x=0;x<6;x++)
System.out.println("demo run-----"+x);
}
}
public class ThreadDemo {
public static void main(String[] args) {
Demo4 d = new Demo4();//创建好一个线程。
d.start();//开启线程并执行该线程的run方法。
//d.run();//仅仅是对象调用方法。而线程创建了,并没有运行。
for(int x=0;x<6;x++)
System.out.println("Hello World!--" + x);
}
}
//输出结果
Hello World!--0
demo run-----0
Hello World!--1
demo run-----1
Hello World!--2
demo run-----2
Hello World!--3
demo run-----3
Hello World!--4
demo run-----4
Hello World!--5
demo run-----5
class Demo4 extends Thread
{
public void run()
{
for (int x=0;x<6;x++)
System.out.println("demo run-----"+x);
}
}
public class ThreadDemo {
public static void main(String[] args) {
Demo4 d = new Demo4();//创建好一个线程。
//d.start();//开启线程并执行该线程的run方法。
d.run();//仅仅是对象调用方法。而线程创建了,并没有运行。
for(int x=0;x<6;x++)
System.out.println("Hello World!--" + x);
}
}
//输出结果
demo run-----0
demo run-----1
demo run-----2
demo run-----3
demo run-----4
demo run-----5
Hello World!--0
Hello World!--1
Hello World!--2
Hello World!--3
Hello World!--4
Hello World!--5
线程都有自己默认的名称,Thread-编号,该编号从0开始。static Thread currentThread():获取当前线程对象。getName():获取线程名称。设置线程名称:setName或者构造函数。
class Test1 extends Thread
{
Test1(String name)
{
super(name);
}
public void run()
{
for (int x=0;x<6;x++)
{
System.out.println(Thread.currentThread().getName()+"run..."+x);
}
}
}
public class ThreadDemo0 {
public static void main(String[] args) {
Test1 t1 = new Test1("one---");
Test1 t2 = new Test1("tw0+++");
t1.start();
t2.start();
for (int i=0;i<6;i++)
System.out.println("Hello world!"+i);
}
}
//输出
Hello world!0
Hello world!1
Hello world!2
Hello world!3
Hello world!4
Hello world!5
one---run...0
one---run...1
one---run...2
tw0+++run...0
one---run...3
tw0+++run...1
one---run...4
tw0+++run...2
one---run...5
tw0+++run...3
tw0+++run...4
tw0+++run...5
创建线程的第二种方式:实现Runnable接口。
步骤:
- 1.定义类实现Runnable接口
- 2.覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。
- 3.通过Thread类建立线程对象。
- 4.将Runable接口的子类对象座位实际参数传递给Thread类的构造函数。为什么要将Runnable接口的子类对象传递给Thread的构造函数。因为,自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去执行指定对象的run方法。就必须明确该run方法所属对象。
- 5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
实现方式和继承方式有什么区别呢?
实现方式好处:避免了单继承的局限性。在定义线程时,建议使用实现方式。
两种方式区别:
继承Thread:线程代码存放Thread子类的run方法中。
实现Runnable:线程代码存在接口的子类的run方法中。
class Ticket implements Runnable
{
private String name;
Ticket(String name)
{
super();
}
private int sum = 100;
public void run(){
while (true)
{
if (sum>0)
System.out.println(Thread.currentThread().getName()+"run---"+sum--);
}
}
}
public class ThreadDemo1 {
public static void main(String[] args) {
Ticket t = new Ticket("火车票");
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
//输出
Thread-0run---100
Thread-0run---96
Thread-2run---98
Thread-1run---99
Thread-3run---97
Thread-1run---93
Thread-2run---94
Thread-0run---95
Thread-2run---90
Thread-1run---91
Thread-3run---92
Thread-1run---87
Thread-2run---88
Thread-0run---89
Thread-0run---83
Thread-0run---82
Thread-0run---81
Thread-2run---84
Thread-1run---85
Thread-3run---86
Thread-3run---77
Thread-1run---78
Thread-1run---75
Thread-1run---74
Thread-1run---73
Thread-2run---79
Thread-0run---80
Thread-2run---71
Thread-1run---72
Thread-1run---68
Thread-1run---67
Thread-3run---76
Thread-1run---66
Thread-2run---69
Thread-0run---70
Thread-2run---63
Thread-1run---64
Thread-3run---65
Thread-1run---60
Thread-2run---61
Thread-0run---62
Thread-2run---57
Thread-1run---58
Thread-3run---59
Thread-1run---54
Thread-2run---55
Thread-0run---56
Thread-2run---51
Thread-1run---52
Thread-3run---53
Thread-1run---48
Thread-2run---49
Thread-0run---50
Thread-2run---45
Thread-1run---46
Thread-3run---47
Thread-1run---42
Thread-2run---43
Thread-0run---44
Thread-2run---39
Thread-1run---40
Thread-3run---41
Thread-1run---36
Thread-2run---37
Thread-0run---38
Thread-2run---33
Thread-1run---34
Thread-3run---35
Thread-1run---30
Thread-2run---31
Thread-0run---32
Thread-2run---27
Thread-1run---28
Thread-3run---29
Thread-1run---24
Thread-2run---25
Thread-0run---26
Thread-2run---21
Thread-1run---22
Thread-3run---23
Thread-1run---18
Thread-2run---19
Thread-0run---20
Thread-2run---15
Thread-1run---16
Thread-3run---17
Thread-1run---12
Thread-2run---13
Thread-0run---14
Thread-2run---9
Thread-1run---10
Thread-3run---11
Thread-1run---6
Thread-2run---7
Thread-0run---8
Thread-2run---3
Thread-1run---4
Thread-3run---5
Thread-2run---1
Thread-0run---2
多线程的运行出现了安全问题。
问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。
解决办法:对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。
Java对于多线程的安全问题提供了专业的解决方式。
就是同步代码块。
synchronized(对象)
{
需要被同步的代码
}
对象如同锁,持有锁的线程可以在同步中执行。没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
火车上的卫生间---经典。
同步的前提:
1.必须要有两个或者两个以上的线程。
2.必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行。
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为消耗资源。
class Ticket implements Runnable
{
private String name;
Ticket(String name)
{
super();
}
private int sum = 100;
public void run()
{
while (true)
{
synchronized (this)
{
if (sum > 0)
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
//
// }
System.out.println(Thread.currentThread().getName() + "run---" + sum--);
}
}
}
}
public class ThreadDemo1 {
public static void main(String[] args) {
Ticket t = new Ticket("火车票");
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
银行存钱的例子
银行有一个金库,有两个储户分别存300元,每次存100元,存3次。
目的:该程序是否有安全问题,如果有,如何解决?
如何找问题:
1.明确哪些代码是多线程运行代码。
2.明确共享数据。
3.明确多线程运行代码中哪些语句是操作共享数据的。
class Bank
{
private int sum;
public void add(int n)
{
try {
Thread.sleep(10);
}catch (InterruptedException e)
{
}
sum = sum + n;
System.out.println(Thread.currentThread().getName()+"sum="+sum);
}
}
class Cus implements Runnable
{
private Bank b = new Bank();
public void run()
{
for (int x=0;x<3;x++)
{
b.add(100);
}
}
}
public class BankDemo {
public static void main(String[] args) {
Cus c = new Cus();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
//输出
Thread-0sum=200
Thread-1sum=200
Thread-1sum=400
Thread-0sum=400
Thread-1sum=500
Thread-0sum=600
添加同步锁
class Bank
{
private int sum;
public void add(int n)
{
synchronized (this)
{
try {
Thread.sleep(10);
}catch (InterruptedException e)
{
}
sum = sum + n;
System.out.println(Thread.currentThread().getName()+"sum="+sum);
}
}
}
class Cus implements Runnable
{
private Bank b = new Bank();
public void run()
{
for (int x=0;x<3;x++)
{
b.add(100);
}
}
}
public class BankDemo {
public static void main(String[] args) {
Cus c = new Cus();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
//输出
Thread-0sum=100
Thread-0sum=200
Thread-0sum=300
Thread-1sum=400
Thread-1sum=500
Thread-1sum=600
设置为同步函数
class Bank
{
private int sum;
public synchronized void add(int n)
{
try {
Thread.sleep(10);
}catch (InterruptedException e)
{
}
sum = sum + n;
System.out.println(Thread.currentThread().getName()+"sum="+sum);
}
}
class Cus implements Runnable
{
private Bank b = new Bank();
public void run()
{
for (int x=0;x<3;x++)
{
b.add(100);
}
}
}
public class BankDemo {
public static void main(String[] args) {
Cus c = new Cus();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
//输出
Thread-0sum=100
Thread-0sum=200
Thread-0sum=300
Thread-1sum=400
Thread-1sum=500
Thread-1sum=600
同步函数用的是哪一个锁呢?函数需要被对象调用,那么函数都有一个所属对象引用,就是this。所以同步函数使用的锁是this。通过该程序进行验证。
- 使用两个线程来买票。
- 一个线程在同步代码块中。
- 一个线程在同步函数中。
- 都在执行买票动作。
class Ticket0 implements Runnable
{
private int tick = 100;
boolean flag = true;
Object obj = new Object();
public void run()
{
if (flag)
{
while (true)
{
synchronized (obj)
{
if (tick > 0) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ".........sale" + tick--);
}
}
}
}
else
while (true)
{
this.show();
}
}
public synchronized void show()
{
if (tick > 0) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ".....code" + tick--);
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
Ticket0 t = new Ticket0();
Thread th0 = new Thread(t);
Thread th1 = new Thread(t);
System.out.println(Thread.currentThread().getName());
th0.start();
try { Thread.sleep(10); } catch (InterruptedException e) {}
t.flag = false;
th1.start();
}
}
//输出
main
Thread-0.........sale100
Thread-1.....code99
Thread-0.........sale98
Thread-1.....code97
Thread-0.........sale96
Thread-1.....code95
Thread-0.........sale94
Thread-1.....code93
Thread-0.........sale92
Thread-1.....code91
Thread-0.........sale90
Thread-1.....code89
Thread-0.........sale88
Thread-1.....code87
Thread-0.........sale86
Thread-1.....code85
Thread-0.........sale84
Thread-1.....code83
Thread-0.........sale82
Thread-1.....code81
Thread-0.........sale80
Thread-1.....code79
Thread-0.........sale78
Thread-1.....code77
Thread-0.........sale76
Thread-1.....code75
Thread-0.........sale74
Thread-1.....code73
Thread-0.........sale72
Thread-1.....code71
Thread-0.........sale70
Thread-1.....code69
Thread-0.........sale68
Thread-1.....code67
Thread-0.........sale66
Thread-1.....code65
Thread-0.........sale64
Thread-1.....code63
Thread-0.........sale62
Thread-1.....code61
Thread-0.........sale60
Thread-1.....code59
Thread-0.........sale58
Thread-1.....code57
Thread-0.........sale56
Thread-1.....code55
Thread-0.........sale54
Thread-1.....code53
Thread-0.........sale52
Thread-1.....code51
Thread-0.........sale50
Thread-1.....code49
Thread-0.........sale48
Thread-1.....code47
Thread-0.........sale46
Thread-1.....code45
Thread-0.........sale44
Thread-1.....code43
Thread-0.........sale42
Thread-1.....code41
Thread-0.........sale40
Thread-1.....code39
Thread-0.........sale38
Thread-1.....code37
Thread-0.........sale36
Thread-1.....code35
Thread-0.........sale34
Thread-1.....code33
Thread-0.........sale32
Thread-1.....code31
Thread-0.........sale30
Thread-1.....code29
Thread-0.........sale28
Thread-1.....code27
Thread-0.........sale26
Thread-1.....code25
Thread-0.........sale24
Thread-1.....code23
Thread-0.........sale22
Thread-1.....code21
Thread-0.........sale20
Thread-1.....code19
Thread-0.........sale18
Thread-1.....code17
Thread-0.........sale16
Thread-1.....code15
Thread-0.........sale14
Thread-1.....code13
Thread-0.........sale12
Thread-1.....code11
Thread-0.........sale10
Thread-1.....code9
Thread-0.........sale8
Thread-1.....code7
Thread-0.........sale6
Thread-1.....code5
Thread-0.........sale4
Thread-1.....code3
Thread-0.........sale2
Thread-1.....code1
Thread-0.........sale0
出现0号票,表明不是同一个锁。
class Ticket0 implements Runnable
{
private int tick = 100;
boolean flag = true;
Object obj = new Object();
public void run()
{
if (flag)
{
while (true)
{
synchronized (this)
{
if (tick > 0) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ".........sale" + tick--);
}
}
}
}
else
while (true)
{
this.show();
}
}
public synchronized void show()
{
if (tick > 0) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ".....code" + tick--);
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
Ticket0 t = new Ticket0();
Thread th0 = new Thread(t);
Thread th1 = new Thread(t);
System.out.println(Thread.currentThread().getName());
th0.start();
try { Thread.sleep(10); } catch (InterruptedException e) {}
t.flag = false;
th1.start();
}
}
//输出正常:两个线程同步卖票
main
Thread-0.........sale100
Thread-0.........sale99
Thread-0.........sale98
Thread-0.........sale97
Thread-0.........sale96
Thread-0.........sale95
Thread-0.........sale94
Thread-0.........sale93
Thread-0.........sale92
Thread-0.........sale91
Thread-0.........sale90
Thread-0.........sale89
Thread-0.........sale88
Thread-0.........sale87
Thread-0.........sale86
Thread-0.........sale85
Thread-0.........sale84
Thread-0.........sale83
Thread-0.........sale82
Thread-0.........sale81
Thread-0.........sale80
Thread-0.........sale79
Thread-0.........sale78
Thread-0.........sale77
Thread-0.........sale76
Thread-0.........sale75
Thread-0.........sale74
Thread-0.........sale73
Thread-0.........sale72
Thread-0.........sale71
Thread-0.........sale70
Thread-0.........sale69
Thread-0.........sale68
Thread-0.........sale67
Thread-0.........sale66
Thread-0.........sale65
Thread-0.........sale64
Thread-0.........sale63
Thread-0.........sale62
Thread-0.........sale61
Thread-0.........sale60
Thread-0.........sale59
Thread-0.........sale58
Thread-0.........sale57
Thread-0.........sale56
Thread-0.........sale55
Thread-0.........sale54
Thread-0.........sale53
Thread-0.........sale52
Thread-0.........sale51
Thread-0.........sale50
Thread-0.........sale49
Thread-0.........sale48
Thread-0.........sale47
Thread-0.........sale46
Thread-0.........sale45
Thread-0.........sale44
Thread-0.........sale43
Thread-0.........sale42
Thread-0.........sale41
Thread-0.........sale40
Thread-0.........sale39
Thread-0.........sale38
Thread-0.........sale37
Thread-0.........sale36
Thread-0.........sale35
Thread-0.........sale34
Thread-0.........sale33
Thread-0.........sale32
Thread-0.........sale31
Thread-0.........sale30
Thread-0.........sale29
Thread-0.........sale28
Thread-0.........sale27
Thread-0.........sale26
Thread-0.........sale25
Thread-0.........sale24
Thread-0.........sale23
Thread-0.........sale22
Thread-0.........sale21
Thread-0.........sale20
Thread-1.....code19
Thread-1.....code18
Thread-1.....code17
Thread-1.....code16
Thread-1.....code15
Thread-1.....code14
Thread-1.....code13
Thread-1.....code12
Thread-1.....code11
Thread-1.....code10
Thread-1.....code9
Thread-1.....code8
Thread-1.....code7
Thread-1.....code6
Thread-1.....code5
Thread-1.....code4
Thread-1.....code3
Thread-1.....code2
Thread-1.....code1
如果同步函数被静态修饰后,使用的锁是什么呢?通过验证,发现不是this,因为静态方法中也不可以定义this。静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。类名.class 该对象的类型是Class。静态的同步方法,使用的锁是该方法所在类的字节码文件对象。类名.class。
class Ticket1 implements Runnable
{
private static int tick = 100;
boolean flag = true;
Object obj = new Object();
public void run()
{
if (flag)
{
while (true)
{
synchronized (obj)
{
if (tick > 0) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ".........sale" + tick--);
}
}
}
}
else
while (true)
{
show();
}
}
public static synchronized void show()
{
if (tick > 0) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ".....code" + tick--);
}
}
}
public class ThreadDemo3 {
public static void main(String[] args) {
Ticket1 t = new Ticket1();
Thread th0 = new Thread(t);
Thread th1 = new Thread(t);
th0.start();
try { Thread.sleep(10); } catch (InterruptedException e) {}
t.flag = false;
th1.start();
}
}
//输出0号票,表明静态同步函数的锁不是obj,也不可能是this。
Thread-1.....code99
Thread-0.........sale100
Thread-1.....code98
Thread-0.........sale98
Thread-1.....code97
Thread-0.........sale97
Thread-1.....code96
Thread-0.........sale96
Thread-0.........sale95
Thread-1.....code95
Thread-0.........sale94
Thread-1.....code94
Thread-1.....code93
Thread-0.........sale93
Thread-1.....code92
Thread-0.........sale92
Thread-0.........sale91
Thread-1.....code91
Thread-1.....code90
Thread-0.........sale90
Thread-1.....code89
Thread-0.........sale89
Thread-1.....code88
Thread-0.........sale87
Thread-0.........sale85
Thread-1.....code86
Thread-0.........sale84
Thread-1.....code83
Thread-0.........sale82
Thread-1.....code82
Thread-0.........sale81
Thread-1.....code81
Thread-0.........sale80
Thread-1.....code80
Thread-0.........sale79
Thread-1.....code79
Thread-0.........sale78
Thread-1.....code78
Thread-0.........sale77
Thread-1.....code77
Thread-0.........sale76
Thread-1.....code76
Thread-1.....code74
Thread-0.........sale75
Thread-1.....code73
Thread-0.........sale72
Thread-1.....code71
Thread-0.........sale70
Thread-0.........sale69
Thread-1.....code69
Thread-1.....code68
Thread-0.........sale67
Thread-1.....code66
Thread-0.........sale65
Thread-1.....code64
Thread-0.........sale63
Thread-1.....code62
Thread-0.........sale61
Thread-1.....code60
Thread-0.........sale59
Thread-1.....code58
Thread-0.........sale58
Thread-1.....code57
Thread-0.........sale56
Thread-1.....code55
Thread-0.........sale54
Thread-0.........sale53
Thread-1.....code53
Thread-0.........sale52
Thread-1.....code52
Thread-1.....code51
Thread-0.........sale51
Thread-0.........sale50
Thread-1.....code50
Thread-0.........sale49
Thread-1.....code49
Thread-0.........sale48
Thread-1.....code47
Thread-1.....code46
Thread-0.........sale46
Thread-1.....code45
Thread-0.........sale44
Thread-0.........sale43
Thread-1.....code43
Thread-1.....code41
Thread-0.........sale42
Thread-1.....code40
Thread-0.........sale39
Thread-1.....code38
Thread-0.........sale37
Thread-1.....code36
Thread-0.........sale35
Thread-1.....code34
Thread-0.........sale33
Thread-1.....code32
Thread-0.........sale31
Thread-0.........sale30
Thread-1.....code29
Thread-0.........sale28
Thread-1.....code27
Thread-1.....code26
Thread-0.........sale25
Thread-0.........sale24
Thread-1.....code24
Thread-1.....code22
Thread-0.........sale23
Thread-1.....code21
Thread-0.........sale21
Thread-0.........sale20
Thread-1.....code19
Thread-0.........sale18
Thread-1.....code17
Thread-0.........sale16
Thread-1.....code15
Thread-1.....code13
Thread-0.........sale14
Thread-0.........sale12
Thread-1.....code12
Thread-0.........sale11
Thread-1.....code10
Thread-0.........sale9
Thread-1.....code8
Thread-0.........sale7
Thread-1.....code6
Thread-0.........sale5
Thread-1.....code4
Thread-0.........sale3
Thread-1.....code2
Thread-0.........sale1
Thread-1.....code0
class Ticket1 implements Runnable
{
private static int tick = 100;
boolean flag = true;
Object obj = new Object();
public void run()
{
if (flag)
{
while (true)
{
synchronized (Ticket1.class)
{
if (tick > 0) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ".........sale" + tick--);
}
}
}
}
else
while (true)
{
show();
}
}
public static synchronized void show()
{
if (tick > 0) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ".....code" + tick--);
}
}
}
public class ThreadDemo3 {
public static void main(String[] args) {
Ticket1 t = new Ticket1();
Thread th0 = new Thread(t);
Thread th1 = new Thread(t);
th0.start();
try { Thread.sleep(10); } catch (InterruptedException e) {}
t.flag = false;
th1.start();
}
}
//输出正常
Thread-0.........sale100
Thread-0.........sale99
Thread-1.....code98
Thread-1.....code97
Thread-1.....code96
Thread-1.....code95
Thread-1.....code94
Thread-1.....code93
Thread-1.....code92
Thread-1.....code91
Thread-1.....code90
Thread-1.....code89
Thread-1.....code88
Thread-1.....code87
Thread-1.....code86
Thread-1.....code85
Thread-1.....code84
Thread-1.....code83
Thread-1.....code82
Thread-1.....code81
Thread-1.....code80
Thread-1.....code79
Thread-1.....code78
Thread-1.....code77
Thread-1.....code76
Thread-1.....code75
Thread-0.........sale74
Thread-0.........sale73
Thread-0.........sale72
Thread-0.........sale71
Thread-0.........sale70
Thread-0.........sale69
Thread-0.........sale68
Thread-0.........sale67
Thread-0.........sale66
Thread-0.........sale65
Thread-0.........sale64
Thread-0.........sale63
Thread-1.....code62
Thread-1.....code61
Thread-1.....code60
Thread-1.....code59
Thread-1.....code58
Thread-1.....code57
Thread-1.....code56
Thread-1.....code55
Thread-1.....code54
Thread-1.....code53
Thread-0.........sale52
Thread-0.........sale51
Thread-0.........sale50
Thread-0.........sale49
Thread-0.........sale48
Thread-1.....code47
Thread-1.....code46
Thread-1.....code45
Thread-1.....code44
Thread-1.....code43
Thread-1.....code42
Thread-1.....code41
Thread-1.....code40
Thread-0.........sale39
Thread-0.........sale38
Thread-0.........sale37
Thread-0.........sale36
Thread-1.....code35
Thread-1.....code34
Thread-1.....code33
Thread-1.....code32
Thread-1.....code31
Thread-1.....code30
Thread-1.....code29
Thread-1.....code28
Thread-1.....code27
Thread-1.....code26
Thread-1.....code25
Thread-1.....code24
Thread-1.....code23
Thread-1.....code22
Thread-1.....code21
Thread-1.....code20
Thread-1.....code19
Thread-1.....code18
Thread-1.....code17
Thread-1.....code16
Thread-1.....code15
Thread-1.....code14
Thread-1.....code13
Thread-1.....code12
Thread-1.....code11
Thread-1.....code10
Thread-1.....code9
Thread-1.....code8
Thread-1.....code7
Thread-1.....code6
Thread-1.....code5
Thread-1.....code4
Thread-1.....code3
Thread-1.....code2
Thread-1.....code1
单例
饿汉式
class Single
{
private static Singele s = new Single();
private Single(){};
private static Single getInstance()
{
returen s;
}
}
懒汉式
class Single
{
private static Single s = null;
private Single(){};
private static Single getInstance()
{
if(s == null)
{
synchronized(Single.class)
{
if(s == null)
s = new Single();
}
}
return s;
}
}
死锁
class Test2 implements Runnable
{
private boolean flag;
Test2(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 lockb");
synchronized (MyLock.locka)
{
System.out.println("else locka");
}
}
}
}
}
class MyLock
{
static Object locka = new Object();
static Object lockb = new Object();
}
public class DeadLockDemo {
public static void main(String[] args) {
Thread t1 = new Thread(new Test2(true));
Thread t2 = new Thread(new Test2(false));
t1.start();
t2.start();
}
}
//输出:程序无法结束,光标一直闪。