Java 多线程Thread start run

  • 进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该程序是一个执行路径,或者叫一个控制单元。
  • 线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。
  • 一个进程中至少有一个线程。
  • 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();
    }
}
//输出:程序无法结束,光标一直闪。
2.gif
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容