ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

创建多线程两种方式参考例子(synchronized)

2022-09-09 12:01:14  阅读:284  来源: 互联网

标签:synchronized Thread 参考 Windows start new ticket 多线程 public


  线程窗口买票例子(存在线程安全问题)   开发中:优先选择Runnable接口的方式 原因:1.实现的方式没有类的单继承性的局限性    2.实现的方式更适合来处理多个线程有共享数据的情况 二者联系:public class Thread implements Runnable 相同点:两种都要重写run(),将线程要执行的逻辑声明再run()中。   创建线程的两种方式选择   方式一:继承Thread类  
public class WindowsTest {
    public static void main(String[] args) {
        // 方式一:继承于Thread类测试
        Window1 w1 = new Window1();
        Window1 w2 = new Window1();
        Window1 w3 = new Window1();
 
        w1.setName("窗口一");
        w2.setName("窗口二");
        w3.setName("窗口三");
 
        w1.start();
        w2.start();
        w3.start();
    }
}
 
class Window1 extends Thread {
    // 使用了static修饰多个线程调用也是只有100张票
    private static int ticket = 100;
  // 重写run()方法
    @Override
    public void run() {
        while (true) {
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket);
                ticket--;
            }else {
                break;
            }
        }
    }
}

 

方式二:实现Runaable接口

 

public class WindowsTest {
    public static void main(String[] args) {
 
        // 方式二:实现Runnable接口测试
        Window w = new Window();
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
 
        t1.setName("窗口一");
        t2.setName("窗口二");
        t3.setName("窗口三");
 
        t1.start();
        t2.start();
        t3.start();
 
    }
}
 
class Window implements Runnable {
 
    private int ticket = 100;
  // 重写run()方法
    @Override
    public void run() {
        while (true) {
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket);
                ticket--;
            }else {
                break;
            }
        }
    }
}

 

 以下解决线程安全问题  

 方式一:同步代码块

 说明:1.操作共享数据代码,即为需要被同步的代码     2.共享数据:多个线程共同操作的变量。比如:ticket就是共享数据     3.同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。          (要求:多个线程必须公用同一把锁。)

 

 继承方式:

 

public class WindowsTest {
    public static void main(String[] args) {
        // 方式一:继承于Thread类测试         
        Windows w1 = new Windows();
        Windows w2 = new Windows();
        Windows w3 = new Windows();               

   // 此时创建了多个对象执行 w1.setName("窗口1"); w2.setName("窗口2"); w3.setName("窗口3"); w1.start(); w2.start(); w3.start(); } } class Windows extends Thread { // 使用了static修饰多个线程调用也是只有100张票 private static int ticket = 100; // 这里需要static来保证锁的唯一性(调用时可能创建了多个对象调用) @Override public void run() { while (true) { synchronized (Windows.class) { if (ticket > 0) {
            // 延时 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket); ticket--; }else { break; } } } } }   

 

实现方式:

 

public class WindowsTest {
    public static void main(String[] args) {
     // 方式二:实现Runnable接口
        Windows w = new Windows();
     // 这边共用了一个对象 Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("窗口一"); t2.setName("窗口二"); t3.setName("窗口三"); t1.start(); t2.start(); t3.start(); } } class Windows implements Runnable { private int ticket = 100; @Override public void run() { while (true) { synchronized (windows.class) { if (ticket > 0) {
            // 延时 try { Thread.sleep(100); }catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket); ticket--; }else { break; } } } } }

 

方式二:同步方法
如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明同步的。

 

继承方式:

 

// 继承于Thread类
public class WindowsTest {
    public static void main(String[] args) {
        Windows w1 = new Windows();
        Windows w2 = new Windows();
        Windows w3 = new Windows();
         
        w1.setName("窗口一");
        w2.setName("窗口二");
        w3.setName("窗口三");
         
        w1.start();
        w2.start();
        w3.start();
    }
}
 
class Windows extends Thread{
     
    private static int ticket = 100;
     
    @Override
    public void run() {
        while (true) {
       // 调用方法 show(); } } // 创建一个方法,将共享数据声明在里方法里 private static synchronized void show() { // private synchronized void show() //同步监视器 w1,w2,w3 if (ticket > 0) { try { Thread.sleep(100); }catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket); ticket--; } } }

 

实现方式:

 

// 实现Runnable接口
public class WindowsTest1 {
    public static void main(String[] args) {
        Windows w = new Windows();
         
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
         
        t1.setName("窗口一");
        t2.setName("窗口二");
        t3.setName("窗口三");
         
        t1.start();
        t2.start();
        t3.start();
    }
}
 
class Windows implements Runnable{
     
    private int ticket = 100;
     
    @Override
    public void run() {
        while (true) {
       // 调用方法 show(); } } // 同步监视器this private synchronized void show() { if (ticket > 0) { try { Thread.sleep(100); }catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket); ticket--; } } }

 

线程安全举例: 

   把厕所比作成共享数据(如以上的ticket),A进去上厕所了还没上完B就也进去上厕所了所以就出现了安全问题,

   解决方法就是在厕所上一把锁等A上完厕所之后B才能进去上厕所,即使A进入后睡了一觉(sleep)也要等A出来

   后B才能进入,从而解决了安全问题。  

标签:synchronized,Thread,参考,Windows,start,new,ticket,多线程,public
来源: https://www.cnblogs.com/lxh-daniel/p/16672220.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有