跳到主要內容

系統化學習多線程(一)

大綱



-------------------------學前必讀----------------------------------


學習不能快速成功,但一定可以快速入門
整體課程思路:
1.實踐為主,理論化偏少
2.課程筆記有完整的案例和代碼,(為了學習效率)再開始之前我會簡單粗暴的介紹知識點案例思路,
有基礎的同學聽了之後可以直接結合筆記寫代碼,
如果沒聽懂再向下看視頻,我會手把手編寫代碼和演示測試結果;
3.重要提示,學編程和學游泳一樣,多實踐學習效率才高,理解才透徹;
4.編碼功底差的建議每個案例代碼寫三遍,至於為什麼...<<賣油翁>>...老祖宗的智慧


-------------------------------------------------------------------------


 1.線程


1.1.什麼是線程


線程(英語:thread)是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以併發多個線程,每條線程并行執行不同的任務。在Unix System V及SunOS中也被稱為輕量進程(lightweight processes),但輕量進程更多指內核線程(kernel thread),而把用戶線程(user thread)稱為線程。(來自百度百科)


一個進程可以有很多線程,每條線程并行執行不同的任務。


1.2.多線程hello word


需求:模擬在計算上一邊聽歌一邊打遊戲


三種實現方案如下:

TestDemo
 1 package com.wfd360.thread;
2
3 import com.wfd360.thread.demo01.GameRunnable;
4 import com.wfd360.thread.demo01.MusicRunnable;
5 import com.wfd360.thread.demo02.GameThread;
6 import com.wfd360.thread.demo02.MusicThread;
7 import org.junit.Test;
8
9 /**
10 * @author 姿勢帝-博客園
11 * @address https://www.cnblogs.com/newAndHui/
12 * @WeChat 851298348
13 * @create 05/03 5:27
14 * @description 需求分析:
15 * 1.模擬一邊打遊戲一邊聽音樂,在控制台打印輸出模擬
16 * 2.把兩個業務封裝成獨立的線程,實現接口Runnable或繼承Thread,通過看源碼你會發現Thread類實現了接口Runnable,使用本質上這兩種方法時一樣的。
17 * 3.Thread類提供兩個方法,線程主題方法run,啟動線程方法start
18 */
19 public class TestDemo {
20 /**
21 * 方式1:實現接口Runnable
22 */
23 @Test
24 public void testRunnable() throws InterruptedException {
25 System.out.println("-------test start-------");
26 // 實例對象
27 MusicRunnable music = new MusicRunnable();
28 GameRunnable game = new GameRunnable();
29 // 創建線程
30 Thread musicThread = new Thread(music);
31 Thread gameThread = new Thread(game);
32 // 啟動線程
33 musicThread.start();
34 gameThread.start();
35 System.out.println("--------等待其他線程執行--------------");
36 Thread.sleep(5 * 1000);
37 System.out.println("-------test end-------");
38 }
39
40 /**
41 * 方式2:繼承Thread
42 */
43 @Test
44 public void testThread() throws InterruptedException {
45 System.out.println("-------test start-------");
46 // 創建線程
47 MusicThread musicThread = new MusicThread();
48 GameThread gameThread = new GameThread();
49 // 啟動線程
50 musicThread.start();
51 gameThread.start();
52 System.out.println("--------等待其他線程執行--------------");
53 Thread.sleep(5 * 1000);
54 System.out.println("-------test end-------");
55 }
56
57 /**
58 * 方式3:簡寫,這種寫法一般我們在做模擬測試的使用,在正式代碼中建議不使用,可讀性較差
59 */
60 @Test
61 public void testThreadSimple() throws InterruptedException {
62 System.out.println("-------test start-------");
63 // 創建線程
64 Thread musicThread = new Thread(() -> {
65 for (int i = 0; i < 100; i++) {
66 System.out.println("=======聽音樂中============" + i);
67 }
68 });
69 Thread gameThread = new Thread(() -> {
70 for (int i = 0; i < 100; i++) {
71 System.out.println("=======打遊戲中============" + i);
72 }
73 });
74 // 啟動線程
75 musicThread.start();
76 gameThread.start();
77 System.out.println("--------等待其他線程執行--------------");
78 Thread.sleep(5 * 1000);
79 System.out.println("-------test end-------");
80 }
81 }



 實現接口Runnable


 1 package com.wfd360.thread.demo01;
2
3 /**
4 * @author 姿勢帝-博客園
5 * @address https://www.cnblogs.com/newAndHui/
6 * @WeChat 851298348
7 * @create 05/03 5:31
8 * @description
9 */
10 public class GameRunnable implements Runnable {
11 @Override
12 public void run() {
13 for (int i = 0; i < 100; i++) {
14 System.out.println("=======打遊戲中============" + i);
15 }
16 }
17 }

GameRunnable
 1 package com.wfd360.thread.demo01;
2
3 /**
4 * @author 姿勢帝-博客園
5 * @address https://www.cnblogs.com/newAndHui/
6 * @WeChat 851298348
7 * @create 05/03 5:29
8 * @description
9 */
10 public class MusicRunnable implements Runnable {
11 @Override
12 public void run() {
13 for (int i = 0; i < 100; i++) {
14 System.out.println("=======聽音樂中============"+i);
15 }
16 }
17 }

MusicRunnable

 繼承Thread


 1 package com.wfd360.thread.demo02;
2
3 /**
4 * @author 姿勢帝-博客園
5 * @address https://www.cnblogs.com/newAndHui/
6 * @WeChat 851298348
7 * @create 05/03 6:00
8 * @description
9 */
10 public class GameThread extends Thread {
11 @Override
12 public void run() {
13 for (int i = 0; i < 100; i++) {
14 System.out.println("-------遊戲中----------"+i);
15 }
16 }
17 }

GameThread GameThread
 1 package com.wfd360.thread.demo02;
2
3 /**
4 * @author 姿勢帝-博客園
5 * @address https://www.cnblogs.com/newAndHui/
6 * @WeChat 851298348
7 * @create 05/03 6:00
8 * @description
9 */
10 public class MusicThread extends Thread {
11 @Override
12 public void run() {
13 for (int i = 0; i < 100; i++) {
14 System.out.println("-------音樂中----------" + i);
15 }
16 }
17 }



 總結


啟動線程兩種方式:


    1.通過繼承Thread類


    2.實現Runnable接口


 使用哪種方式更好?


區別: 


一個類如果繼承了其他類,就無法在繼承Thread類,在Java中,一個類只能繼承一個類,而一個類如果實現了一個接口,還可以實現其他接口,接口是可以多實現的,所以說


Runable的擴展性更強,但是繼承的方式更簡單,個人建議一般情況下使用Thread;


實現接口Runnable或繼承Thread,通過看源碼你會發現Thread類實現了接口Runnable,使用本質上這兩種方法是一樣的

啟動線程流程:


    創建啟動線程的方式一:繼承Thread類


       1.將業務方法封裝成線程對象,自定義類t extends Thread類; 


       2.覆寫run方法: 覆寫第一步中的run方法;


       3.創建自定義對象t


       4.啟動線程 t.start();


   創建啟動線程方式二:實現Runnable接口


      1.將業務方法封裝成線程對象,自定義類t implements Runnable接口;


      2.實現第一步中的run方法


      3.創建自定義對象t


      4.啟動線程 new Thread(t).start();


1.3.對主線程與創建線程執行順序的理解


問題:
直接寫一個簡單的HelloWorld 程序,有沒有線程?
==>有一個主線程,在垃圾回收的時候,有gc 線程。


 1 package com.wfd360.thread;
2
3 import org.junit.Test;
4
5 /**
6 * @author 姿勢帝-博客園
7 * @address https://www.cnblogs.com/newAndHui/
8 * @WeChat 851298348
9 * @create 05/04 11:09
10 * @description <p>
11 * 問題:
12 * 直接寫一個簡單的HelloWorld 程序,有沒有線程?
13 * ==>有一個主線程,在垃圾回收的時候,有gc 線程。
14 * 結論:一旦線程啟動起來之後就是獨立的,和創建環境沒有關係;
15 * 啟動線程不能直接調用run方法,必須調用start方法;
16 * </p>
17 */
18 public class TestDemo02 {
19 /**
20 * 如果把創建線程放在循環語句的 下 面,會交替出現嗎
21 * ==>否,因為主線程執行完成后才會啟動hello線程
22 *
23 * @throws Exception
24 */
25 @Test
26 public void test1() throws Exception {
27 System.out.println("---test start-------");
28 // 執行主線程
29 for (int i = 0; i < 100; i++) {
30 System.out.println("-----test1--------" + i);
31 }
32 // 啟動hello線程
33 new HelloThread().start();
34 System.out.println("=======等待執行完成===========");
35 Thread.sleep(5 * 1000);
36 System.out.println("---test end-------");
37 }
38
39 /**
40 * 如果把創建線程放在循環語句的 上 面,會交替出現嗎
41 * ==>可能會,可能不會,可能出現for循環完之後,線程還沒有啟動完;
42 *
43 * @throws Exception
44 */
45 @Test
46 public void test2() throws Exception {
47 System.out.println("---test start-------");
48 // 啟動hello線程
49 new HelloThread().start();
50 // 執行主線程
51 for (int i = 0; i < 100; i++) {
52 System.out.println("-----test1--------" + i);
53 }
54 System.out.println("=======等待執行完成===========");
55 Thread.sleep(5 * 1000);
56 System.out.println("---test end-------");
57 }
58
59 /**
60 * 採用內部類的方式定義一個hello線程對象
61 */
62 class HelloThread extends Thread {
63 @Override
64 public void run() {
65 for (int i = 0; i < 100; i++) {
66 System.out.println("-----HelloThread--------" + i);
67 }
68 }
69 }
70 }

TestDemo02

結論:一旦線程啟動起來之後就是獨立的,和創建環境沒有關係;
啟動線程不能直接調用run方法,必須調用start方法;


 1.4.對sleep方法的理解


package com.wfd360.thread;

/**
*
@author 姿勢帝-博客園
* @address
https://www.cnblogs.com/newAndHui/
* @WeChat 851298348
* @create 05/04 11:34
* @description <p>
* Thread類的方法:
* static void sleep(long millis) 在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行);
* </p>
*/
public class TestSleep {
/**
* 做一個簡易倒計時,10秒鐘,控制台每一秒輸出一個数字,如10,9,8,7.....0
*/
public static void main(String[] args) throws Exception {
System.out.println(
"---test start-------");
for (int i = 10; i >= 0; i--) {
Thread.sleep(
1 * 1000);
System.out.println(i);
}
System.out.println(
"---test end-------");
}
}

1.5.線程名稱的設置與獲取


繼承方式


簡單需求:使用多線程模擬多窗口售票


 1 package com.wfd360.thread.demo03Ticket;
2
3 /**
4 * @author 姿勢帝-博客園
5 * @address https://www.cnblogs.com/newAndHui/
6 * @WeChat 851298348
7 * @create 05/04 11:55
8 * @description <p>
9 * 模擬多線程售票
10 * </p>
11 */
12 public class TicketThread extends Thread {
13 // 假定票總是100張
14 private static Integer num = 100;
15
16 @Override
17 public void run() {
18 // 只要有票就一直售票
19 while (num > 0) {
20 System.out.println("正在出售第" + num + "張票");
21 --num;
22 }
23 System.out.println("===售票結束===");
24 }
25 }

TicketThread

test


/**
* 測試模擬三個窗口售票
*
@throws InterruptedException
*/
@Test
public void testTicketThread() throws InterruptedException {
System.out.println(
"---test start-------");
// 模擬多3個窗口售票
TicketThread ticketThread1 = new TicketThread();
TicketThread ticketThread2
= new TicketThread();
TicketThread ticketThread3
= new TicketThread();
// 啟動線程售票
ticketThread1.start();
ticketThread2.start();
ticketThread3.start();
System.out.println(
"======等待售票============");
Thread.sleep(
5 * 1000);
System.out.println(
"---test end-------");
}

結果:



1.在售票過程中不能區分售出的票是那個窗口售出的,解決通過線程名稱判斷


2.有重複售出的票(後面的線程同步解決)


解決第一個問題,設置獲取線程名稱,通過Thread對象裏面自帶的getName,setName方法



 具體代碼


設置線程名稱



 獲取線程名稱



 上面講了繼承的方式獲取線程名稱,那麼實現接口Runnable的方式怎麼獲取設置勒


繼承Thread的方式,可以通過getName的方式獲取當前線程的名稱?
那使用Runnable的方式,能通過getName獲取嘛?


getName方法是Thread類的,但是TicketThread現在並沒有繼承Thread類,而是實現了Runnable接口.


問題:如果實現Runnable接口,怎麼獲取線程名稱?


 思考:TicketThread類裏面的代碼要執行,它肯定存在於某個線程中, 就比如寫個helloword打印語句,是不是也處於一個主線程中,那這裏怎麼獲取線程名稱?
通過動態獲取,當程序正在執行的時候,獲取當前正在執行的線程名稱。怎麼獲取?
在Thread類裏面有個靜態的方法currentThread() 方法,返回當前正在執行的線程引用;


Thread.currentThread().getName


那怎麼設置線程名稱?


Thread類裏面有個name字段,相當於Thread類把它包裝了一下:


通過源碼可以發現,構造方法裏面還有可以傳一個名字:



具體實現代碼如下



 


 總結:


繼承方式設置\獲取線程名稱通過 Thread對象裏面的 setName,getName方法;


實現接口方式設置名稱通過 new Thread('線程實例對象', "線程名稱"),獲取線程名稱通過:Thread.currentThread().getName


1.6.Thread的join方法


void join() 方法 :等待該線程終止
void join(long millis) 方法 :等待該線程終止的時間最長為millis毫秒


需求: 當主線程運行到20的時候(i =20)的時候,讓JoinThread線程加進來直到執行完成,在執行主線程.


 1 package com.wfd360.thread;
2
3 import org.junit.Test;
4
5 /**
6 * @author 姿勢帝-博客園
7 * @address https://www.cnblogs.com/newAndHui/
8 * @WeChat 851298348
9 * @create 05/04 6:31
10 * @description
11 */
12 public class Test05Join {
13 /**
14 * 需求:
15 * 當主線程for循環到i=20時,等JoinThread線程執行完成后,在執行for循環的線程
16 * @throws InterruptedException
17 */
18 @Test
19 public void testJoinThread() throws InterruptedException {
20 System.out.println("---test start-------");
21 // 開啟線程
22 JoinThread thread = new JoinThread();
23 thread.start();
24 // 循環打印線程
25 for (int i = 0; i < 100; i++) {
26 System.out.println("======testJoinThread=========="+i);
27 Thread.sleep(1);
28 if (i==20){
29 // 等線程JoinThread執行完成
30 thread.join();
31 }
32 }
33 System.out.println("=============等待線程執行完成===================");
34 Thread.sleep(10*1000);
35 System.out.println("---test end-------");
36 }
37
38 class JoinThread extends Thread {
39 @Override
40 public void run() {
41 for (int i = 0; i < 100; i++) {
42 System.out.println("=====JoinThread=======" + i);
43 // 模擬處理很多業務耗時1毫秒
44 try {
45 Thread.sleep(1);
46 } catch (InterruptedException e) {
47 e.printStackTrace();
48 }
49 }
50 }
51 }
52 }

Test05Join

1.7.線程優先級


直接上代碼


 1 package com.wfd360.thread;
2
3 /**
4 * @author 姿勢帝-博客園
5 * @address https://www.cnblogs.com/newAndHui/
6 * @WeChat 851298348
7 * @create 05/05 8:17
8 * @description <p>
9 * 1.==>線程優先級的理解:
10 * 線程的優先級和生活中類似,高優先級線程的執行優先於低優先級線程;
11 * 並不是絕對的,可能優先級高的線程優先 比 優先級低的線程先執行,只能說,高優先級的線程優先執行的幾率更多;
12 * (比如兩個線程,一個優先級高,一個優先級低,如果一共運行一個小時,優先級高的線程執行遠遠大於優先級低的但是並不是說優先級高的先執行完,
13 * 在執行優先級低的)
14 * 2.==>重新設置線程優先級
15 * int getPriority() 返回線程的優先級。
16 * void setPriority(int newPriority) 更改線程的優先級。Java線程的優先級從1到10級別,值越大優先級越高.
17 * 3.==>線程的默認優先級受創建線程的環境影響,默認值5,自定義線程的默認優先級和創建它的環境的線程優先級一致
18 * </p>
19 */
20 public class Test06Priority {
21 /**
22 * 測試獲取線程優先級,設置線程優先級,驗證線程優先級受創建環境影響
23 * @param args
24 */
25 public static void main(String[] args) {
26 Thread threadMain = Thread.currentThread();
27 // 獲取默認優先級数字
28 System.out.println("main線程默認優先級:" +threadMain.getPriority());// 5
29 // 重新設置默認優先級数字
30 threadMain.setPriority(8);
31 // 再次重新獲取優先級数字
32 System.out.println("main線程修改后的優先級:" +threadMain.getPriority());// 8
33 // 創建一個線程查看優先級
34 Thread thread = new Thread();
35 System.out.println("thread線程的優先級:" +thread.getPriority());// 8 受創建環境影響
36 }
37 }

1.8.後台線程,即守護線程


直接看代碼


 1 package com.wfd360.thread;
2
3 import com.wfd360.thread.demo04Daemon.DaemonThreaad;
4
5 /**
6 * @author 姿勢帝-博客園
7 * @address https://www.cnblogs.com/newAndHui/
8 * @WeChat 851298348
9 * @create 05/05 9:12
10 * @description <p>
11 * 後台線程,即守護線程
12 * 後台線程:指為其他線程提供服務的線程,也稱為守護線程。JVM的垃圾回收線程就是一個後台線程。
13 * 需求:嘗試把線程標記為後台線程或者標記為(前台)線程;
14 * Thread類提供的方法:
15 * 方法1: void setDaemon(boolean on) 將該線程標記為守護線程或用戶線程,true為後台線程,false為用戶線程(前台線下)
16 * 怎樣測試該線程是否是守護線程?
17 * 方法2:isDaemon() 測試該線程是否為守護線程. true為後台線程,false為用戶線程(前台線下)
18 * <p>
19 * 結論1:活動的線程(已經在執行的線程t.start())不能設置後台線程,即主線程不能設置為後台線程。
20 * 結論2: 自定義線程的默認狀態和環境有關,後台線程中創建的線程默認是後台線程,前台線程中創建的線程為前台線程.
21 * 結論3: 前台線程執行完后,會直接關閉後台線程,即自定義的後台線程不一定能執行完成
22 * </p>
23 */
24 public class Test07Daemon {
25 /**
26 * 測試1
27 * 查看主線程的狀態,嘗試更改
28 * 結論:活動的線程不能設置為後台線程
29 *
30 * @param args
31 */
32 public static void main1(String[] args) {
33 Thread threadMain = Thread.currentThread();
34 System.out.println("是後台線程么:" + threadMain.isDaemon());// false
35 threadMain.setDaemon(true); // 報錯,活動的線程不能設置為後台線程
36 System.out.println("修改后是後台線程么:" + threadMain.isDaemon());
37 }
38
39 /**
40 * 測試2
41 * 查看主線程中 創建線程的狀態,嘗試更改;
42 *
43 * @param args
44 */
45 public static void main2(String[] args) {
46 Thread thread = new Thread();
47 // false
48 System.out.println("是後台線程么:" + thread.isDaemon());
49 // 修改為後台線程
50 thread.setDaemon(true);
51 System.out.println("修改后是後台線程么:" + thread.isDaemon());
52 }
53
54 /**
55 * 測試3
56 * 查看主線程中 創建線程的狀態,嘗試更改,讓線程處於活動狀態在修改->報錯;
57 *
58 * @param args
59 */
60 public static void main3(String[] args) {
61 DaemonThread thread = new DaemonThread();
62 // 讓線程處於活躍狀態
63 thread.start();
64 // false
65 System.out.println("是後台線程么:" + thread.isDaemon());
66 // 修改為後台線程,報錯,當前已經是活躍狀態(thread.start())不能修改為後台線程
67 thread.setDaemon(true);
68 System.out.println("修改后是後台線程么:" + thread.isDaemon());
69 }
70
71 /**
72 * 測試4
73 * 前台線程執行完后,會直接關閉後台線程,即如果後台線程不一定能執行完成
74 * 可以通過修改等待執行時間來觀察DaemonThread線程的數組輸出變化
75 *
76 * @param args
77 */
78 public static void main(String[] args) throws InterruptedException {
79 DaemonThread thread = new DaemonThread();
80 // 修改為後台線程
81 thread.setDaemon(true);
82 // 讓線程處於活躍狀態
83 thread.start();
84 System.out.println("========等待後台線程執行============");
85 Thread.sleep(5 * 1000);
86 }
87 }

 1 package com.wfd360.thread.demo04Daemon;
2
3 /**
4 * @author 姿勢帝-博客園
5 * @address https://www.cnblogs.com/newAndHui/
6 * @WeChat 851298348
7 * @create 05/05 9:27
8 * @description
9 */
10 public class DaemonThread extends Thread {
11 @Override
12 public void run() {
13 for (int i = 0; i < 10; i++) {
14 System.out.println("===="+i);
15 try {
16 Thread.sleep(1000);
17 } catch (InterruptedException e) {
18 e.printStackTrace();
19 }
20 }
21 }
22 }

DaemonThread

線程基礎相關的方法定義就先到這裏,下一篇我們將進入線程同步.


https://www.cnblogs.com/newAndHui/p/12831089.html


系統化的在線學習:點擊進入學習

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】



網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!



※台北網頁設計公司全省服務真心推薦



※想知道最厲害的網頁設計公司"嚨底家"!



※推薦評價好的iphone維修中心



網頁設計最專業,超強功能平台可客製化



※別再煩惱如何寫文案,掌握八大原則!



Orignal From: 系統化學習多線程(一)

留言

這個網誌中的熱門文章

掃地機器人可以隨身帶上飛機嗎?我想要拿去送給國外的朋友

掃地機器人如果要隨身戴上飛機需要滿足兩個條件: 一個是掃地機器人連同你的隨身行李,整體的體積和重量要符合上機條件,這個具體每家航空公司都不同,可以諮詢,簡單的說就是隨身行李不要超寬超重。 還有一個就是由於掃地機器人內置了鋰電池,所以內置電池的容量要符合相關規定,每個掃地機器人電池容量都不同,具體自行查詢。 根據民航的相關安全要求,凡帶有鋰電池的電子設備均不可以托運,但符合重量要求,尺寸要求以及電量要求的鋰電池及其設備是可以帶上飛機的。 《鋰電池航空運輸規範》中內含鋰離子電池的設備電池額定能量不應超過100Wh的規定,符合國標GB31241-2014,並通過UN38.3航空運輸認證等國際安全標準,所以可以帶上飛機。但是不能托運,只能隨身攜帶。 掃地機器人     掃地機器人     掃地機器人吸塵器 http://www.greenh3y.com/?p=400 Orignal From: 掃地機器人可以隨身帶上飛機嗎?我想要拿去送給國外的朋友

不滿國際規範斷財路 非洲多國擬退野生動保公約

摘錄自2019年09月01日中央通訊社非洲報導 非洲南部多國揚言退出「瀕臨絕種野生動植物國際貿易公約」,因為公約多數成員拒絕放寬象牙與犀牛角交易,並且幾乎全面禁止將野生捕獲的大象送到動物園。 這個公約嚴格規範全球野生動物交易,包括限制象牙與犀牛角交易。 本週在日內瓦召開修訂「瀕臨絕種野生動植物國際貿易公約」(CITES)的會議期間,由於區域集團非南開發共同體(SADC)的多項提案遭否決,這個集團與公約的關係惡化。 全球大象數量最多的區域波札那、納米比亞與辛巴威要求販售取自自然死亡、充公與汰除的大象象牙,這項提議被居多數的101票否決。 40多年前制訂的CITES規範約3萬6000種動植物交易,並設計有助於遏止非法交易和制裁違規國家的機制。 不過有16個成員國的非南開發共同體部分會員批評CITES對非洲國家的問題視若無睹。 坦尚尼亞環境部長西蒙巴徹恩(George Simbachawene)於日內瓦召開的會議中表示:「結果無法採取進步、公平、包容與基於科學的的保育策略。」 他說:「該是認真重新考慮我們加入CITES是否有任何實質益處的時候了。」 本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理 【搬家相關資訊指南】 台中搬家 , 彰化搬家 , 南投搬家 前需注意的眉眉角角,別等搬了再說! 避免吃悶虧無故遭抬價! 台中搬家公司 免費估價,有契約讓您安心有保障! 評比 彰化搬家公司費用 , 南投搬家公司費用 收費行情懶人包大公開 彰化搬家費用 , 南投搬家費用 ,距離,噸數怎麼算?達人教你簡易估價知識! Orignal From: 不滿國際規範斷財路 非洲多國擬退野生動保公約

全球第一國 帛琉立法禁用、禁售防曬乳

摘錄自2018年11月2日蘋果日報帛琉報導 為了保護珊瑚礁生態,帛琉政府昨(1)日表示已立法嚴禁販售並使用防曬乳,此法將於2020年1月1日起正式生效。帛琉也成為全球首個全面禁止防曬乳的國家。 帛琉國會上周通過此法案,全面禁止使用和販售含有10種有害化學物質的防曬乳,違者將被處以1000美元(約3萬783元台幣)罰款。若遊客被發現私帶防曬乳入境,也會遭到沒收。帛琉總統雷蒙傑索(Tommy Remengesau)說:「沒收(防曬乳)已經足夠讓人不進行商業使用,而這也是很聰明的一招,一方面教育觀光客,又不會把他們嚇跑。」 根據官方說法,帛琉的熱門潛水點每小時會有4艘載著觀光客的船隻造訪,他們身上的防曬乳化學物質相當可觀。總統府發言人說:「帛琉各潛水和浮潛地點每天都有好幾加崙的防曬乳入海。我們只是盡力要防止環境遭受污染。」 本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理 【其他文章推薦】 ※ 台中搬家 , 彰化搬家 , 南投搬家 前需注意的眉眉角角,別等搬了再說! ※在找尋 搬家 公司嗎? ※搬家不受騙不被宰 桃園搬家公司 , 桃園市搬家公司 公開報價讓你比價不吃虧! Orignal From: 全球第一國 帛琉立法禁用、禁售防曬乳